diff --git a/BMap/BMExports.cpp b/BMap/BMExports.cpp index 73b9c32..596f126 100644 --- a/BMap/BMExports.cpp +++ b/BMap/BMExports.cpp @@ -1,16 +1,47 @@ #include "BMExports.hpp" #include #include +#include +#include + +#pragma region Help & Save Functions static bool g_IsInited = false; static std::set g_AllBMFiles = std::set(); static std::set g_AllBMMeshTrans = std::set(); +bool CheckInited() { + return g_IsInited; +} + +bool CheckBMFile(BMap::BMFile* possible_bmfile) { + return (g_IsInited && possible_bmfile != nullptr && g_AllBMFiles.contains(possible_bmfile)); +} + +bool CheckBMMeshTrans(BMap::BMMeshTransition* possible_trans) { + return (g_IsInited && possible_trans != nullptr && g_AllBMMeshTrans.contains(possible_trans)); +} + +template, int> = 0> +_Ty CheckCKObject(BMap::BMFile* possible_bmfile, LibCmo::CK2::CK_ID possible_id, LibCmo::CK2::CK_CLASSID expected_cid) { + // check bm file self. + if (!CheckBMFile(possible_bmfile)) return nullptr; + // check id + LibCmo::CK2::ObjImpls::CKObject* obj = possible_bmfile->GetObjectPtr(possible_id); + // check id validation and class id + if (obj == nullptr || LibCmo::CK2::CKIsChildClassOf(obj->GetClassID(), expected_cid)) return nullptr; + + return static_cast<_Ty>(obj); +} + +#pragma endregion + void BMInit() { // register IronPad IronPad::IronPadRegister(); // and startup CK environment LibCmo::CK2::CKStartUp(); + // set init g_IsInited = true; } @@ -29,6 +60,7 @@ void BMDispose() { // disable init g_IsInited = false; + // shutdown CK environment LibCmo::CK2::CKShutdown(); // unregister iron pad @@ -38,141 +70,180 @@ void BMDispose() { #pragma region BMFile BMap::BMFile* BMFile_Load(LibCmo::CKSTRING file_name, LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[]) { - if (!g_IsInited) return nullptr; - auto file = new BMap::BMFile(temp_folder, texture_folder, encoding_count, encodings, false); - if (file->IsFailed()) { - delete file; - file = nullptr; - } - if (!file->Load(file_name)) { - delete file; - file = nullptr; - } + if (!CheckInited()) return nullptr; - g_AllBMFiles.emplace(file); - return file; + // create a now one and try to load data. + std::unique_ptr file(new BMap::BMFile(temp_folder, texture_folder, encoding_count, encodings, false)); + if (file->IsFreezed()) return nullptr; + if (!file->Load(file_name)) return nullptr; + + // add into list and return + g_AllBMFiles.emplace(file.get()); + return file.release(); } BMap::BMFile* BMFile_Create(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[]) { - if (!g_IsInited) return nullptr; - auto file = new BMap::BMFile(temp_folder, texture_folder, encoding_count, encodings, false); - if (file->IsFailed()) { - delete file; - file = nullptr; - } + if (!CheckInited()) return nullptr; - g_AllBMFiles.emplace(file); - return file; + // create a now one + std::unique_ptr file(new BMap::BMFile(temp_folder, texture_folder, encoding_count, encodings, false)); + if (file->IsFreezed()) return nullptr; + + // add into list and return if success + g_AllBMFiles.emplace(file.get()); + return file.release(); } bool BMFile_Save(BMap::BMFile* map_file, LibCmo::CKSTRING file_name, LibCmo::CKINT compreess_level) { - if (!g_AllBMFiles.contains(map_file)) return false; + if (!CheckBMFile(map_file)) return false; + return map_file->Save(file_name, compreess_level); } -void BMFile_Free(BMap::BMFile* map_file) { - // only free correct pointer - if (map_file == nullptr) return; - if (g_AllBMFiles.erase(map_file) != 0) { - delete map_file; - } +bool BMFile_Free(BMap::BMFile* map_file) { + if (!CheckBMFile(map_file)) return false; + + g_AllBMFiles.erase(map_file); + delete map_file; + return true; } -#define VISITOR_IMPL(namepart, cidpart) \ -LibCmo::CKDWORD BMFile_Get ## namepart ## Count(BMap::BMFile* map_file) { \ - if (!g_AllBMFiles.contains(map_file)) return 0; \ - return map_file->Get ## namepart ## Count(); \ -} \ -LibCmo::CK2::ObjImpls::CK ## namepart * BMFile_Get ## namepart (BMap::BMFile* map_file, LibCmo::CKDWORD idx) { \ - if (!g_AllBMFiles.contains(map_file)) return nullptr; \ - return map_file->Get ## namepart (idx); \ -} \ -LibCmo::CK2::ObjImpls::CK ## namepart * BMFile_Create ## namepart (BMap::BMFile* map_file, LibCmo::CKSTRING name) { \ - if (!g_AllBMFiles.contains(map_file)) return nullptr; \ - return map_file->Create ## namepart (name); \ +LibCmo::CKDWORD BMFile_GetGroupCount(BMap::BMFile* bmfile) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetGroupCount(); +} +LibCmo::CK2::CK_ID BMFile_GetGroup(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetGroup(idx); +} +LibCmo::CK2::CK_ID BMFile_CreateGroup(BMap::BMFile* bmfile, LibCmo::CKSTRING name) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->CreateGroup(name); +} +LibCmo::CKDWORD BMFile_Get3dObjectCount(BMap::BMFile* bmfile) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->Get3dObjectCount(); +} +LibCmo::CK2::CK_ID BMFile_Get3dObject(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->Get3dObject(idx); +} +LibCmo::CK2::CK_ID BMFile_Create3dObject(BMap::BMFile* bmfile, LibCmo::CKSTRING name) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->Create3dObject(name); +} +LibCmo::CKDWORD BMFile_GetMeshCount(BMap::BMFile* bmfile) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetMeshCount(); +} +LibCmo::CK2::CK_ID BMFile_GetMesh(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetMesh(idx); +} +LibCmo::CK2::CK_ID BMFile_CreateMesh(BMap::BMFile* bmfile, LibCmo::CKSTRING name) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->CreateMesh(name); +} +LibCmo::CKDWORD BMFile_GetMaterialCount(BMap::BMFile* bmfile) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetMaterialCount(); +} +LibCmo::CK2::CK_ID BMFile_GetMaterial(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetMaterial(idx); +} +LibCmo::CK2::CK_ID BMFile_CreateMaterial(BMap::BMFile* bmfile, LibCmo::CKSTRING name) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->CreateMaterial(name); +} +LibCmo::CKDWORD BMFile_GetTextureCount(BMap::BMFile* bmfile) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetTextureCount(); +} +LibCmo::CK2::CK_ID BMFile_GetTexture(BMap::BMFile* bmfile, LibCmo::CKDWORD idx) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->GetTexture(idx); +} +LibCmo::CK2::CK_ID BMFile_CreateTexture(BMap::BMFile* bmfile, LibCmo::CKSTRING name) { + if (!CheckBMFile(bmfile)) return 0; + return bmfile->CreateTexture(name); } - -VISITOR_IMPL(Group, GROUP) -VISITOR_IMPL(3dObject, 3DOBJECT) -VISITOR_IMPL(Mesh, MESH) -VISITOR_IMPL(Material, MATERIAL) -VISITOR_IMPL(Texture, TEXTURE) - -#undef VISITOR_IMPL #pragma endregion #pragma region BMMeshTransition BMap::BMMeshTransition* BMMeshTrans_New() { - if (!g_IsInited) return nullptr; + if (!CheckInited()) return nullptr; + + // create new one, insert and return. auto meshtrans = new BMap::BMMeshTransition(); g_AllBMMeshTrans.emplace(meshtrans); return meshtrans; } -void BMMeshTrans_Delete(BMap::BMMeshTransition* trans) { - // only free correct pointer - if (trans == nullptr) return; - if (g_AllBMMeshTrans.erase(trans) != 0) { - delete trans; - } +bool BMMeshTrans_Delete(BMap::BMMeshTransition* trans) { + if (!CheckBMMeshTrans(trans)) return false; + + g_AllBMMeshTrans.erase(trans); + delete trans; + return true; } -void BMMeshTrans_PrepareVertexCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { - if (!g_AllBMMeshTrans.contains(trans)) return; - trans->PrepareVertexCount(count); +bool BMMeshTrans_PrepareVertexCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { + if (!CheckBMMeshTrans(trans)) return false; + return trans->PrepareVertexCount(count); } LibCmo::VxMath::VxVector3* BMMeshTrans_PrepareVertex(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareVertex(); } -void BMMeshTrans_PrepareNormalCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { - if (!g_AllBMMeshTrans.contains(trans)) return; - trans->PrepareNormalCount(count); +bool BMMeshTrans_PrepareNormalCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { + if (!CheckBMMeshTrans(trans)) return false; + return trans->PrepareNormalCount(count); } LibCmo::VxMath::VxVector3* BMMeshTrans_PrepareNormal(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareNormal(); } -void BMMeshTrans_PrepareUVCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { - if (!g_AllBMMeshTrans.contains(trans)) return; - trans->PrepareUVCount(count); +bool BMMeshTrans_PrepareUVCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { + if (!CheckBMMeshTrans(trans)) return false; + return trans->PrepareUVCount(count); } LibCmo::VxMath::VxVector2* BMMeshTrans_PrepareUV(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareUV(); } -void BMMeshTrans_PrepareMtlSlotCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { - if (!g_AllBMMeshTrans.contains(trans)) return; - trans->PrepareMtlSlotCount(count); +bool BMMeshTrans_PrepareMtlSlotCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { + if (!CheckBMMeshTrans(trans)) return false; + return trans->PrepareMtlSlotCount(count); } LibCmo::CK2::ObjImpls::CKMaterial** BMMeshTrans_PrepareMtlSlot(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareMtlSlot(); } -void BMMeshTrans_PrepareFaceCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { - if (!g_AllBMMeshTrans.contains(trans)) return; - trans->PrepareFaceCount(count); +bool BMMeshTrans_PrepareFaceCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count) { + if (!CheckBMMeshTrans(trans)) return false; + return trans->PrepareFaceCount(count); } LibCmo::CKDWORD* BMMeshTrans_PrepareFaceVertexIndices(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareFaceVertexIndices(); } LibCmo::CKDWORD* BMMeshTrans_PrepareFaceNormalIndices(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareFaceNormalIndices(); } LibCmo::CKDWORD* BMMeshTrans_PrepareFaceUVIndices(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareFaceUVIndices(); } LibCmo::CKDWORD* BMMeshTrans_PrepareFaceMtlSlot(BMap::BMMeshTransition* trans) { - if (!g_AllBMMeshTrans.contains(trans)) return nullptr; + if (!CheckBMMeshTrans(trans)) return nullptr; return trans->PrepareFaceMtlSlot(); } bool BMMeshTrans_Parse(BMap::BMMeshTransition* trans, LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh) { - if (!g_AllBMMeshTrans.contains(trans)) return false; + if (!CheckBMMeshTrans(trans)) return false; return trans->Parse(write_into_mesh); } diff --git a/BMap/BMExports.hpp b/BMap/BMExports.hpp index 1accfbd..0dbf0f3 100644 --- a/BMap/BMExports.hpp +++ b/BMap/BMExports.hpp @@ -14,43 +14,45 @@ LIBCMO_EXPORT void BMDispose(); LIBCMO_EXPORT BMap::BMFile* BMFile_Load(LibCmo::CKSTRING file_name, LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[]); LIBCMO_EXPORT BMap::BMFile* BMFile_Create(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[]); LIBCMO_EXPORT bool BMFile_Save(BMap::BMFile* map_file, LibCmo::CKSTRING file_name, LibCmo::CKINT compreess_level); -LIBCMO_EXPORT void BMFile_Free(BMap::BMFile* map_file); +LIBCMO_EXPORT bool BMFile_Free(BMap::BMFile* map_file); -#define VISITOR_DECL(namepart) \ -LIBCMO_EXPORT LibCmo::CKDWORD BMFile_Get ## namepart ## Count(BMap::BMFile* map_file); \ -LIBCMO_EXPORT LibCmo::CK2::ObjImpls::CK ## namepart * BMFile_Get ## namepart (BMap::BMFile* map_file, LibCmo::CKDWORD idx); \ -LIBCMO_EXPORT LibCmo::CK2::ObjImpls::CK ## namepart * BMFile_Create ## namepart (BMap::BMFile* map_file, LibCmo::CKSTRING name); - -VISITOR_DECL(Group) -VISITOR_DECL(3dObject) -VISITOR_DECL(Mesh) -VISITOR_DECL(Material) -VISITOR_DECL(Texture) - -#undef VISITOR_DECL +LIBCMO_EXPORT LibCmo::CKDWORD BMFile_GetGroupCount(BMap::BMFile* bmfile); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_GetGroup(BMap::BMFile* bmfile, LibCmo::CKDWORD idx); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_CreateGroup(BMap::BMFile* bmfile, LibCmo::CKSTRING name); +LIBCMO_EXPORT LibCmo::CKDWORD BMFile_Get3dObjectCount(BMap::BMFile* bmfile); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_Get3dObject(BMap::BMFile* bmfile, LibCmo::CKDWORD idx); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_Create3dObject(BMap::BMFile* bmfile, LibCmo::CKSTRING name); +LIBCMO_EXPORT LibCmo::CKDWORD BMFile_GetMeshCount(BMap::BMFile* bmfile); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_GetMesh(BMap::BMFile* bmfile, LibCmo::CKDWORD idx); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_CreateMesh(BMap::BMFile* bmfile, LibCmo::CKSTRING name); +LIBCMO_EXPORT LibCmo::CKDWORD BMFile_GetMaterialCount(BMap::BMFile* bmfile); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_GetMaterial(BMap::BMFile* bmfile, LibCmo::CKDWORD idx); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_CreateMaterial(BMap::BMFile* bmfile, LibCmo::CKSTRING name); +LIBCMO_EXPORT LibCmo::CKDWORD BMFile_GetTextureCount(BMap::BMFile* bmfile); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_GetTexture(BMap::BMFile* bmfile, LibCmo::CKDWORD idx); +LIBCMO_EXPORT LibCmo::CK2::CK_ID BMFile_CreateTexture(BMap::BMFile* bmfile, LibCmo::CKSTRING name); #pragma endregion #pragma region BMMeshTransition LIBCMO_EXPORT BMap::BMMeshTransition* BMMeshTrans_New(); -LIBCMO_EXPORT void BMMeshTrans_Delete(BMap::BMMeshTransition* trans); +LIBCMO_EXPORT bool BMMeshTrans_Delete(BMap::BMMeshTransition* trans); -LIBCMO_EXPORT void BMMeshTrans_PrepareVertexCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); +LIBCMO_EXPORT bool BMMeshTrans_PrepareVertexCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); LIBCMO_EXPORT LibCmo::VxMath::VxVector3* BMMeshTrans_PrepareVertex(BMap::BMMeshTransition* trans); -LIBCMO_EXPORT void BMMeshTrans_PrepareNormalCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); +LIBCMO_EXPORT bool BMMeshTrans_PrepareNormalCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); LIBCMO_EXPORT LibCmo::VxMath::VxVector3* BMMeshTrans_PrepareNormal(BMap::BMMeshTransition* trans); -LIBCMO_EXPORT void BMMeshTrans_PrepareUVCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); +LIBCMO_EXPORT bool BMMeshTrans_PrepareUVCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); LIBCMO_EXPORT LibCmo::VxMath::VxVector2* BMMeshTrans_PrepareUV(BMap::BMMeshTransition* trans); -LIBCMO_EXPORT void BMMeshTrans_PrepareMtlSlotCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); +LIBCMO_EXPORT bool BMMeshTrans_PrepareMtlSlotCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); LIBCMO_EXPORT LibCmo::CK2::ObjImpls::CKMaterial** BMMeshTrans_PrepareMtlSlot(BMap::BMMeshTransition* trans); -LIBCMO_EXPORT void BMMeshTrans_PrepareFaceCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); +LIBCMO_EXPORT bool BMMeshTrans_PrepareFaceCount(BMap::BMMeshTransition* trans, LibCmo::CKDWORD count); LIBCMO_EXPORT LibCmo::CKDWORD* BMMeshTrans_PrepareFaceVertexIndices(BMap::BMMeshTransition* trans); LIBCMO_EXPORT LibCmo::CKDWORD* BMMeshTrans_PrepareFaceNormalIndices(BMap::BMMeshTransition* trans); LIBCMO_EXPORT LibCmo::CKDWORD* BMMeshTrans_PrepareFaceUVIndices(BMap::BMMeshTransition* trans); LIBCMO_EXPORT LibCmo::CKDWORD* BMMeshTrans_PrepareFaceMtlSlot(BMap::BMMeshTransition* trans); LIBCMO_EXPORT bool BMMeshTrans_Parse(BMap::BMMeshTransition* trans, LibCmo::CK2::ObjImpls::CKMesh* write_into_mesh); - #pragma endregion diff --git a/BMap/BMap.cpp b/BMap/BMap.cpp index 821bc6a..267755a 100644 --- a/BMap/BMap.cpp +++ b/BMap/BMap.cpp @@ -28,11 +28,12 @@ namespace BMap { m_ProcVertexs(), m_ProcFaces(), m_ProcDupRemover() {} BMMeshTransition::~BMMeshTransition() {} - - void BMMeshTransition::PrepareVertexCount(LibCmo::CKDWORD count) { - if (m_IsParsed) return; + + bool BMMeshTransition::PrepareVertexCount(LibCmo::CKDWORD count) { + if (m_IsParsed) return false; m_Vertexs.resize(count); m_IsVertexOK = true; + return true; } LibCmo::VxMath::VxVector3* BMMeshTransition::PrepareVertex() { @@ -40,10 +41,11 @@ namespace BMap { return m_Vertexs.data(); } - void BMMeshTransition::PrepareNormalCount(LibCmo::CKDWORD count) { - if (m_IsParsed) return; + bool BMMeshTransition::PrepareNormalCount(LibCmo::CKDWORD count) { + if (m_IsParsed) return false; m_Normals.resize(count); m_IsNormalOK = true; + return true; } LibCmo::VxMath::VxVector3* BMMeshTransition::PrepareNormal() { @@ -51,10 +53,11 @@ namespace BMap { return m_Normals.data(); } - void BMMeshTransition::PrepareUVCount(LibCmo::CKDWORD count) { - if (m_IsParsed) return; + bool BMMeshTransition::PrepareUVCount(LibCmo::CKDWORD count) { + if (m_IsParsed) return false; m_UVs.resize(count); m_IsUVOK = true; + return true; } LibCmo::VxMath::VxVector2* BMMeshTransition::PrepareUV() { @@ -62,10 +65,11 @@ namespace BMap { return m_UVs.data(); } - void BMMeshTransition::PrepareMtlSlotCount(LibCmo::CKDWORD count) { - if (m_IsParsed) return; + bool BMMeshTransition::PrepareMtlSlotCount(LibCmo::CKDWORD count) { + if (m_IsParsed) return false; m_MtlSlots.resize(count, nullptr); m_IsMtlSlotOK = true; + return true; } LibCmo::CK2::ObjImpls::CKMaterial** BMMeshTransition::PrepareMtlSlot() { @@ -73,13 +77,14 @@ namespace BMap { return m_MtlSlots.data(); } - void BMMeshTransition::PrepareFaceCount(LibCmo::CKDWORD count) { - if (m_IsParsed) return; + bool BMMeshTransition::PrepareFaceCount(LibCmo::CKDWORD count) { + if (m_IsParsed) return false; m_FaceVertexs.resize(count * 3); m_FaceNormals.resize(count * 3); m_FaceUVs.resize(count * 3); m_FaceMtlSlotIdxs.resize(count); m_IsFaceOK = true; + return true; } LibCmo::CKDWORD* BMMeshTransition::PrepareFaceVertexIndices() { @@ -217,12 +222,12 @@ namespace BMap { #pragma region BMfile BMFile::BMFile(LibCmo::CKSTRING temp_folder, LibCmo::CKSTRING texture_folder, LibCmo::CKDWORD encoding_count, LibCmo::CKSTRING encodings[], bool is_reader) : - m_IsReader(is_reader), m_IsFailed(false) { + m_IsReader(is_reader), m_IsFreezed(false) { m_Context = new LibCmo::CK2::CKContext(); // set temp folder and texture folder auto pm = m_Context->GetPathManager(); - m_IsFailed = m_IsFailed || !pm->AddPath(texture_folder); - m_IsFailed = m_IsFailed || !pm->SetTempFolder(temp_folder); + m_IsFreezed = m_IsFreezed || !pm->AddPath(texture_folder); + m_IsFreezed = m_IsFreezed || !pm->SetTempFolder(temp_folder); // set encoding LibCmo::XContainer::XArray cache; for (LibCmo::CKDWORD i = 0; i < encoding_count; ++i) { @@ -238,43 +243,54 @@ namespace BMap { delete m_Context; } - bool BMFile::IsFailed() { - return m_IsFailed; + bool BMFile::IsFreezed() { + return m_IsFreezed; } bool BMFile::Load(LibCmo::CKSTRING filename) { - return false; + if (m_IsFreezed || !m_IsReader) return false; + + return true; } bool BMFile::Save(LibCmo::CKSTRING filename, LibCmo::CKINT compress_level) { - return false; + if (m_IsFreezed || m_IsReader) return false; + + // set freezed to stop any change again. + // aka, only allow save once. + m_IsFreezed = true; + return true; } -#define VISITOR_IMPL(namepart, cidpart) \ -LibCmo::CKDWORD BMFile::Get ## namepart ## Count() { \ - if (!m_IsReader) return 0; \ - return static_cast(m_Obj ## namepart ## s.size()); \ -} \ -LibCmo::CK2::ObjImpls::CK ## namepart * BMFile::Get ## namepart (LibCmo::CKDWORD idx) { \ - if (!m_IsReader || idx >= m_Obj ## namepart ## s.size()) return nullptr; \ - return m_Obj ## namepart ## s[idx]; \ -} \ -LibCmo::CK2::ObjImpls::CK ## namepart * BMFile::Create ## namepart (LibCmo::CKSTRING name) { \ - if (m_IsReader) return nullptr; \ - LibCmo::CK2::ObjImpls::CK ## namepart * obj = static_cast( \ - m_Context->CreateObject(LibCmo::CK2::CK_CLASSID::CKCID_ ## cidpart, name) \ - ); \ - if (obj != nullptr) m_Obj ## namepart ## s.emplace_back(obj); \ - return obj; \ -} + LibCmo::CK2::ObjImpls::CKObject* BMFile::GetObjectPtr(LibCmo::CK2::CK_ID objid) { + return m_Context->GetObject(objid);; + } - VISITOR_IMPL(Group, GROUP) - VISITOR_IMPL(3dObject, 3DOBJECT) - VISITOR_IMPL(Mesh, MESH) - VISITOR_IMPL(Material, MATERIAL) - VISITOR_IMPL(Texture, TEXTURE) - -#undef VISITOR_IMPL + LibCmo::CKDWORD BMFile::GetGroupCount() { return CommonGetObjectCount(m_ObjGroups); } + LibCmo::CK2::CK_ID BMFile::GetGroup(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjGroups, idx); } + LibCmo::CK2::CK_ID BMFile::CreateGroup(LibCmo::CKSTRING name) { + return CommonCreateObject(m_ObjGroups, LibCmo::CK2::CK_CLASSID::CKCID_GROUP, name); + } + LibCmo::CKDWORD BMFile::Get3dObjectCount() { return CommonGetObjectCount(m_Obj3dObjects); } + LibCmo::CK2::CK_ID BMFile::Get3dObject(LibCmo::CKDWORD idx) { return CommonGetObject(m_Obj3dObjects, idx); } + LibCmo::CK2::CK_ID BMFile::Create3dObject(LibCmo::CKSTRING name) { + return CommonCreateObject(m_Obj3dObjects, LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT, name); + } + LibCmo::CKDWORD BMFile::GetMeshCount() { return CommonGetObjectCount(m_ObjMeshs); } + LibCmo::CK2::CK_ID BMFile::GetMesh(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjMeshs, idx); } + LibCmo::CK2::CK_ID BMFile::CreateMesh(LibCmo::CKSTRING name) { + return CommonCreateObject(m_ObjMeshs, LibCmo::CK2::CK_CLASSID::CKCID_MESH, name); + } + LibCmo::CKDWORD BMFile::GetMaterialCount() { return CommonGetObjectCount(m_ObjMaterials); } + LibCmo::CK2::CK_ID BMFile::GetMaterial(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjMaterials, idx); } + LibCmo::CK2::CK_ID BMFile::CreateMaterial(LibCmo::CKSTRING name) { + return CommonCreateObject(m_ObjMaterials, LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL, name); + } + LibCmo::CKDWORD BMFile::GetTextureCount() { return CommonGetObjectCount(m_ObjTextures); } + LibCmo::CK2::CK_ID BMFile::GetTexture(LibCmo::CKDWORD idx) { return CommonGetObject(m_ObjTextures, idx); } + LibCmo::CK2::CK_ID BMFile::CreateTexture(LibCmo::CKSTRING name) { + return CommonCreateObject(m_ObjTextures, LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE, name); + } #pragma endregion diff --git a/BMap/BMap.hpp b/BMap/BMap.hpp index 00fb988..b99a0f2 100644 --- a/BMap/BMap.hpp +++ b/BMap/BMap.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace BMap { @@ -32,15 +33,15 @@ namespace BMap { ~BMMeshTransition(); LIBCMO_DISABLE_COPY_MOVE(BMMeshTransition); - void PrepareVertexCount(LibCmo::CKDWORD count); + bool PrepareVertexCount(LibCmo::CKDWORD count); LibCmo::VxMath::VxVector3* PrepareVertex(); - void PrepareNormalCount(LibCmo::CKDWORD count); + bool PrepareNormalCount(LibCmo::CKDWORD count); LibCmo::VxMath::VxVector3* PrepareNormal(); - void PrepareUVCount(LibCmo::CKDWORD count); + bool PrepareUVCount(LibCmo::CKDWORD count); LibCmo::VxMath::VxVector2* PrepareUV(); - void PrepareMtlSlotCount(LibCmo::CKDWORD count); + bool PrepareMtlSlotCount(LibCmo::CKDWORD count); LibCmo::CK2::ObjImpls::CKMaterial** PrepareMtlSlot(); - void PrepareFaceCount(LibCmo::CKDWORD count); + bool PrepareFaceCount(LibCmo::CKDWORD count); LibCmo::CKDWORD* PrepareFaceVertexIndices(); LibCmo::CKDWORD* PrepareFaceNormalIndices(); LibCmo::CKDWORD* PrepareFaceUVIndices(); @@ -78,38 +79,73 @@ namespace BMap { ~BMFile(); LIBCMO_DISABLE_COPY_MOVE(BMFile); - bool IsFailed(); + // ===== help functions ===== + + /** + * @brief Check whether this instance is freezed. + * @return True if freezed. This instance should be free immediately. + */ + bool IsFreezed(); bool Load(LibCmo::CKSTRING filename); bool Save(LibCmo::CKSTRING filename, LibCmo::CKINT compress_level); + LibCmo::CK2::ObjImpls::CKObject* GetObjectPtr(LibCmo::CK2::CK_ID objid); -#define VISITOR_DECL(namepart) \ -LibCmo::CKDWORD Get ## namepart ## Count(); \ -LibCmo::CK2::ObjImpls::CK ## namepart * Get ## namepart (LibCmo::CKDWORD idx); \ -LibCmo::CK2::ObjImpls::CK ## namepart * Create ## namepart (LibCmo::CKSTRING name); - - VISITOR_DECL(Group) - VISITOR_DECL(3dObject) - VISITOR_DECL(Mesh) - VISITOR_DECL(Material) - VISITOR_DECL(Texture) - -#undef VISITOR_DECL + // ===== visitors ===== private: - bool m_IsFailed; + LibCmo::CKDWORD CommonGetObjectCount(std::vector& container) { + if (m_IsFreezed || !m_IsReader) return 0; + return static_cast(container.size()); + } + LibCmo::CK2::CK_ID CommonGetObject(std::vector& container, LibCmo::CKDWORD idx) { + if (m_IsFreezed || !m_IsReader || idx >= container.size()) return 0; + return container[idx]; + } + LibCmo::CK2::CK_ID CommonCreateObject(std::vector& container, LibCmo::CK2::CK_CLASSID cid, LibCmo::CKSTRING name) { + // only available in writer + if (m_IsFreezed || m_IsReader) return 0; + + // try create object and get its pointer + LibCmo::CK2::ObjImpls::CKObject* obj = m_Context->CreateObject(cid, name); + // check creation validation + if (obj == nullptr) return 0; + + // if success, write its id and emplace its id into list + LibCmo::CK2::CK_ID objid = obj->GetID(); + container.emplace_back(objid); + return objid; + } + public: + LibCmo::CKDWORD GetGroupCount(); + LibCmo::CK2::CK_ID GetGroup(LibCmo::CKDWORD idx); + LibCmo::CK2::CK_ID CreateGroup(LibCmo::CKSTRING name); + LibCmo::CKDWORD Get3dObjectCount(); + LibCmo::CK2::CK_ID Get3dObject(LibCmo::CKDWORD idx); + LibCmo::CK2::CK_ID Create3dObject(LibCmo::CKSTRING name); + LibCmo::CKDWORD GetMeshCount(); + LibCmo::CK2::CK_ID GetMesh(LibCmo::CKDWORD idx); + LibCmo::CK2::CK_ID CreateMesh(LibCmo::CKSTRING name); + LibCmo::CKDWORD GetMaterialCount(); + LibCmo::CK2::CK_ID GetMaterial(LibCmo::CKDWORD idx); + LibCmo::CK2::CK_ID CreateMaterial(LibCmo::CKSTRING name); + LibCmo::CKDWORD GetTextureCount(); + LibCmo::CK2::CK_ID GetTexture(LibCmo::CKDWORD idx); + LibCmo::CK2::CK_ID CreateTexture(LibCmo::CKSTRING name); + + private: + /** + * @brief True if all operation of this instance should be rejected. + */ + bool m_IsFreezed; bool m_IsReader; LibCmo::CK2::CKContext* m_Context; -#define VISITOR_SELF(namepart) \ -std::vector m_Obj ## namepart ## s; + std::vector m_ObjGroups; + std::vector m_Obj3dObjects; + std::vector m_ObjMeshs; + std::vector m_ObjMaterials; + std::vector m_ObjTextures; - VISITOR_SELF(Group) - VISITOR_SELF(3dObject) - VISITOR_SELF(Mesh) - VISITOR_SELF(Material) - VISITOR_SELF(Texture) - -#undef VISITOR_SELF }; }