diff --git a/build/premake/premake.lua b/build/premake/premake.lua index 663df4acda..5eac5573f2 100755 --- a/build/premake/premake.lua +++ b/build/premake/premake.lua @@ -106,7 +106,8 @@ if (OS == "windows") then "openal", "spidermonkey", "xerces", - "vorbis" + "vorbis", + "boost" } -- Add '//lib' and '/include' to the includepaths and libpaths diff --git a/source/graphics/MeshManager.cpp b/source/graphics/MeshManager.cpp index 0672f43079..336476b7d2 100755 --- a/source/graphics/MeshManager.cpp +++ b/source/graphics/MeshManager.cpp @@ -1,6 +1,7 @@ #include "precompiled.h" #include "graphics/MeshManager.h" #include "CLogger.h" +#include "FileUnpacker.h" // to get access to its CError CMeshManager::CMeshManager() { @@ -10,71 +11,38 @@ CMeshManager::~CMeshManager() { } -CModelDef *CMeshManager::GetMesh(const char *filename) +CModelDefPtr CMeshManager::GetMesh(const char *filename) { - mesh_map::iterator iter; CStr fn(filename); - if((iter = m_MeshMap.find(fn)) == m_MeshMap.end()) + mesh_map::iterator iter = m_MeshMap.find(fn); + if (iter != m_MeshMap.end()) { - try - { - CModelDef *model = CModelDef::Load(filename); - if(!model) - return NULL; - - LOG(MESSAGE, "mesh", "Loading mesh '%s'...\n", filename); - model->m_Filename = fn; - model->m_RefCount = 1; - m_MeshMap[fn] = model; - return model; - } - catch(...) - { - LOG(ERROR, "mesh", "Could not load mesh '%s'\n!", filename); - return NULL; - } - } - else - { - LOG(MESSAGE, "mesh", "Loading mesh '%s%' (cached)...\n", filename); - CModelDef *model = (CModelDef *)(*iter).second; - model->m_RefCount++; - return model; - } -} - -int CMeshManager::ReleaseMesh(CModelDef* mesh) -{ - if(!mesh) - return 0; - - // FIXME: Someone sort this out. I'm tired. - // Looks like it might be a multiple delete; not sure best way - // to resolve it. MT. - - mesh_map::iterator iter; + try + { + CModelDefPtr model (iter->second); + LOG(MESSAGE, "mesh", "Loading mesh '%s%' (cached)...\n", filename); + return model; + } + // If the mesh has already been deleted, the weak_ptr -> shared_ptr + // conversion will throw bad_weak_ptr (and we need to reload the mesh) + catch (boost::bad_weak_ptr) + { + } + } try { - iter = m_MeshMap.find(mesh->m_Filename); + CModelDefPtr model (CModelDef::Load(filename)); + if (!model) + return CModelDefPtr(); + + LOG(MESSAGE, "mesh", "Loading mesh '%s'...\n", filename); + m_MeshMap[fn] = model; + return model; } - catch( ... ) + catch (CFileUnpacker::CError) { - debug_out( "FIXME: Do something with %s(%d)", __FILE__, __LINE__ ); - return( 0 ); + LOG(ERROR, "mesh", "Could not load mesh '%s'\n!", filename); + return CModelDefPtr(); } - - if(iter == m_MeshMap.end()) - return 0; - - mesh->m_RefCount--; - if(mesh->m_RefCount <= 0) - { - m_MeshMap.erase(iter); - delete mesh; - mesh = NULL; - return 0; - } - - return mesh->m_RefCount; } diff --git a/source/graphics/MeshManager.h b/source/graphics/MeshManager.h index d80693a416..689d901f6b 100755 --- a/source/graphics/MeshManager.h +++ b/source/graphics/MeshManager.h @@ -4,9 +4,14 @@ #include "Singleton.h" #include "graphics/ModelDef.h" +#include "boost/shared_ptr.hpp" +#include "boost/weak_ptr.hpp" + #define g_MeshManager CMeshManager::GetSingleton() -typedef STL_HASH_MAP mesh_map; +typedef STL_HASH_MAP, CStr_hash_compare> mesh_map; + +typedef boost::shared_ptr CModelDefPtr; class CMeshManager : public Singleton { @@ -14,8 +19,7 @@ public: CMeshManager(); ~CMeshManager(); - CModelDef *GetMesh(const char *filename); - int ReleaseMesh(CModelDef* mesh); + CModelDefPtr GetMesh(const char *filename); private: mesh_map m_MeshMap; }; diff --git a/source/graphics/Model.cpp b/source/graphics/Model.cpp index 778b21cc32..86c49385c3 100755 --- a/source/graphics/Model.cpp +++ b/source/graphics/Model.cpp @@ -19,7 +19,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor CModel::CModel() - : m_pModelDef(0), m_Flags(0), m_Anim(0), m_AnimTime(0), + : m_Flags(0), m_Anim(0), m_AnimTime(0), m_BoneMatrices(0), m_InvBoneMatrices(0), m_BoneMatricesValid(false) { } @@ -41,13 +41,12 @@ void CModel::ReleaseData() delete m_Props[i].m_Model; } m_Props.clear(); - if(m_pModelDef) - g_MeshManager.ReleaseMesh(m_pModelDef); + m_pModelDef = CModelDefPtr(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // InitModel: setup model from given geometry -bool CModel::InitModel(CModelDef* modeldef) +bool CModel::InitModel(CModelDefPtr modeldef) { // clean up any existing data first ReleaseData(); @@ -289,6 +288,7 @@ void CModel::AddProp(SPropPoint* point,CModel* model) uint i; for (i=0;iGetModelDef() : 0; - - // try and create a model - CModelDef* modeldef; + CModelDefPtr oldmodeldef=m_Model ? m_Model->GetModelDef() : CModelDefPtr(); const char* modelfilename = m_ModelName.c_str(); - try { - //modeldef=CModelDef::Load(modelfilename); - modeldef = g_MeshManager.GetMesh(modelfilename); - if(!modeldef) - throw false; - } catch (...) { + // try and create a model + CModelDefPtr modeldef (g_MeshManager.GetMesh(modelfilename)); + if (!modeldef) + { LOG(ERROR, LOG_CATEGORY, "CObjectEntry::BuildModel(): Model %s failed to load", modelfilename); return false; } @@ -81,15 +76,15 @@ bool CObjectEntry::BuildModel() const char* animfilename = m_Animations[t].m_FileName.c_str(); m_Animations[t].m_AnimData = m_Model->BuildAnimation(animfilename,m_Animations[t].m_Speed); - if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) ) + if( m_Animations[t].m_AnimName.LowerCase() == "idle" ) m_IdleAnim = m_Animations[t].m_AnimData; - if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) ) + if( m_Animations[t].m_AnimName.LowerCase() == "walk" ) m_WalkAnim = m_Animations[t].m_AnimData; - if( m_Animations[t].m_AnimName.LowerCase() == CStr( "attack" ) ) + if( m_Animations[t].m_AnimName.LowerCase() == "attack" ) m_MeleeAnim = m_Animations[t].m_AnimData; - if( m_Animations[t].m_AnimName.LowerCase() == CStr( "death" ) ) + if( m_Animations[t].m_AnimName.LowerCase() == "death" ) m_DeathAnim = m_Animations[t].m_AnimData; - if( m_Animations[t].m_AnimName.LowerCase() == CStr( "decay" ) ) + if( m_Animations[t].m_AnimName.LowerCase() == "decay" ) m_CorpseAnim = m_Animations[t].m_AnimData; } else @@ -158,9 +153,6 @@ bool CObjectEntry::BuildModel() } } - // and were done with the old model .. - delete oldmodeldef; - return true; } diff --git a/source/renderer/ModelRData.cpp b/source/renderer/ModelRData.cpp index f3193bfd0c..8d34232af9 100755 --- a/source/renderer/ModelRData.cpp +++ b/source/renderer/ModelRData.cpp @@ -54,7 +54,7 @@ void CModelRData::Build() void CModelRData::BuildIndices() { - CModelDef* mdef=m_Model->GetModelDef(); + CModelDefPtr mdef=m_Model->GetModelDef(); assert(mdef); // must have a valid vertex buffer by this point so we know where indices are supposed to start @@ -138,7 +138,7 @@ static void SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices,C void CModelRData::BuildVertices() { - CModelDef* mdef=m_Model->GetModelDef(); + CModelDefPtr mdef=m_Model->GetModelDef(); // allocate vertices if we haven't got any already if (!m_Vertices) { @@ -184,7 +184,7 @@ void CModelRData::BuildVertices() void CModelRData::RenderStreams(u32 streamflags) { - CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef(); + CModelDefPtr mdldef=m_Model->GetModelDef(); if (streamflags & STREAM_UV0) { @@ -243,7 +243,7 @@ float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam) float mindist=1.0e30f; CVector3D osvtx,csvtx; - CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef(); + CModelDefPtr mdldef=m_Model->GetModelDef(); SModelVertex* vtxs=mdldef->GetVertices();