// H3DContainer.h: interface for the CH3DContainer class template. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_H3DCONTAINER_H__EFFCAF0D_E084_4326_8D7C_BD0CAF16EB34__INCLUDED_) #define AFX_H3DCONTAINER_H__EFFCAF0D_E084_4326_8D7C_BD0CAF16EB34__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 //#include "FunctionPerformanceCheck.h" #include #include "misc.h" #include #include #include #include "Z3DStringTable.h" /*namespace ppuchuu{ template class map { public: struct _element_t { _element_t( _key_t _k, _data_t _d ) { first = _k; second = _d; } _key_t first; _data_t second; }; typedef std::vector<_element_t>::iterator iterator; map() { } ~map() { } _data_t& operator []( _key_t &_k ) { for(int i = 0; i < (int)m_vecActualData.size(); ++i ) { if( _k == m_vecActualData[i].first ) { return m_vecActualData[i].second; } } _element_t _e( _k, _data_t() ); m_vecActualData.push_back( _e ); return m_vecActualData[m_vecActualData.size()-1].second; } iterator find( _key_t &_k ) { iterator it; for( it = m_vecActualData.begin(); it != m_vecActualData.end(); it++ ) { if( _k == it->first ) { return it; } } return it; } iterator begin() { return m_vecActualData.begin(); } iterator end() { return m_vecActualData.end(); } void erase( iterator it ) { m_vecActualData.erase( it ); } protected: std::vector<_element_t> m_vecActualData; }; } */ // UID under Win32 file system... /*struct H3D_FILE_UID { public: H3D_FILE_UID( int i ) { dwVolumeSerialNumber = 0UL; dwFileIndexHigh = 0UL; dwFileIndexLow = 0UL; } H3D_FILE_UID() { } bool operator == ( const H3D_FILE_UID &op ) const { return ( (dwVolumeSerialNumber == op.dwVolumeSerialNumber) && (dwFileIndexHigh == op.dwFileIndexHigh) && (dwFileIndexLow == op.dwFileIndexLow) ); } bool operator < ( const H3D_FILE_UID &op ) const { if( dwVolumeSerialNumber < op.dwVolumeSerialNumber ) { return true; } if( dwFileIndexHigh < op.dwFileIndexHigh ) { return true; } if( dwFileIndexLow < op.dwFileIndexLow ) { return true; } return false; } DWORD dwVolumeSerialNumber; DWORD dwFileIndexHigh; DWORD dwFileIndexLow; };*/ template class CH3DContainer; template struct H3DContainerTag { friend class CH3DContainer<_obj>; public: H3DContainerTag() { m_rpObject = NULL; //m_UIDFile = H3D_FILE_UID(0); m_UIDFile = NULL_TOK; m_rpContainer = NULL; } _obj* GetObject() { return m_rpObject; } bool Release() { bool bRet; if( m_rpContainer ) { bRet = m_rpContainer->Release( m_UIDFile ); } //m_UIDFile = H3D_FILE_UID(0); m_UIDFile = NULL_TOK; m_rpObject = NULL; m_rpContainer = NULL; return bRet; } bool operator == ( const H3DContainerTag<_obj> &op ) { return ( m_UIDFile == op.m_UIDFile ); } protected: _obj* m_rpObject; //H3D_FILE_UID m_UIDFile; Z3DTOK m_UIDFile; CH3DContainer<_obj>* m_rpContainer; }; template class CH3DContainer { friend struct H3DContainerTag<_obj>; public: CH3DContainer() { m_szFilePath = NULL; } ~CH3DContainer(); void SetFilePath( const char* szPath ); bool GetObject( H3DContainerTag<_obj> &tag, const char* szFileName ); /*bool LoadHandleNameTable( const char* szFilename, const char* szPath = NULL ) { // dummy function for intermediate compatibility SetFilePath( szPath ); return true; }*/ bool PreLoadAll( const char* szFileSpec ); void FlushAll(); protected: struct H3DContainerElement { int lRefCount; _obj* pObj; H3DContainerElement() { lRefCount = 0; pObj = NULL; } }; //bool Release( H3D_FILE_UID hf ); bool Release( Z3DTOK hf ); char* m_szFilePath; std::map m_mapContainerElement; //std::map m_mapContainerElement; //ppuchuu::map m_mapContainerElement; }; template void CH3DContainer<_obj>::SetFilePath( const char* szPath ) { long lLen = strlen(szPath); if( 0 == lLen ) { return; } if( szPath[lLen-1] != '\\' && szPath[lLen-1] != '/' ) { ++lLen; } m_szFilePath = new char[lLen+1]; strcpy( m_szFilePath, szPath ); m_szFilePath[lLen-1] = '/'; m_szFilePath[lLen] = '\0'; } template bool CH3DContainer<_obj>::GetObject( H3DContainerTag<_obj> &tag, const char* szFileName ) { //DeclareBlockTimingCheck( "before CreateFile", aa ); //DeclareBlockTimingCheck( "CreateFile", bb ); //DeclareBlockTimingCheck( "GetFileInformationByHandle", cc ); //DeclareBlockTimingCheck( "CloseHandle", dd ); if( NULL == szFileName ) { //tag.m_UIDFile = H3D_FILE_UID(0); tag.m_UIDFile = NULL_TOK; tag.m_rpObject = NULL; tag.m_rpContainer = NULL; return false; } // ÆÄÀϸíÀ¸·ÎºÎÅÍ file UID ¸¦ ¾ò´Â´Ù. //H3D_FILE_UID hfu; Z3DTOK hfu; static char szFullPathName[MAX_PATH]; // full path ÀÛ¼º szFullPathName[0] = '\0'; if( m_szFilePath ) { strcpy( szFullPathName, m_szFilePath ); } strcat( szFullPathName, szFileName ); /*HANDLE hFile = CreateFile( szFullPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );*/ // ÆÄÀÏÀÇ Á¸Àç¿Í ¹«°üÇÏ°Ô ÀÏ´Ü ½ºÆ®¸µÅ×ÀÌºí¿¡ ÆÄÀϸíÀ» Ãß°¡Çسõ´Â´Ù.(µî·ÏµÈ °ÍÀ» ã´Â°Ô ¾Æ´Ô) hfu = g_TokFileName.Add( szFullPathName ); /*if( INVALID_HANDLE_VALUE == hFile ) { //tag.m_UIDFile = H3D_FILE_UID(0); tag.m_UIDFile = NULL_TOK; tag.m_rpObject = NULL; tag.m_rpContainer = NULL; return false; } BY_HANDLE_FILE_INFORMATION hfi; if( 0 == GetFileInformationByHandle( hFile, &hfi ) ) { CloseHandle( hFile ); //tag.m_UIDFile = H3D_FILE_UID(0); tag.m_UIDFile = NULL_TOK; tag.m_rpObject = NULL; tag.m_rpContainer = NULL; return false; } hfu.dwVolumeSerialNumber = hfi.dwVolumeSerialNumber; hfu.dwFileIndexHigh = hfi.nFileIndexHigh; hfu.dwFileIndexLow = hfi.nFileIndexLow; CloseHandle( hFile );*/ // map¿¡¼­ file UID¸¦ Ű·Î ¿¤·¹¸àÆ®¸¦ ¾ò¾î¿Â´Ù H3DContainerElement celem = m_mapContainerElement[hfu]; if( NULL == celem.pObj ) { // ¿¤·¹¸àÆ®ÀÇ ¿ÀºêÁ§Æ® Æ÷ÀÎÅͰ¡ ³Î -> µ¥ÀÌÅÍ ¾ÆÁ÷ ·ÎµùµÇÁö ¾ÊÀº°ÍÀ̹ǷΠ·Îµù. celem.pObj = new _obj; if( false == celem.pObj->Load( szFullPathName ) ) { // ÆÄÀÏ ·Îµù ½ÇÆÐ½Ã //tag.m_UIDFile = H3D_FILE_UID(0); SAFE_DELETE( celem.pObj ); tag.m_UIDFile = NULL_TOK; tag.m_rpObject = NULL; tag.m_rpContainer = NULL; return false; } } ++celem.lRefCount; m_mapContainerElement[hfu] = celem; tag.m_rpObject = celem.pObj; tag.m_UIDFile = hfu; tag.m_rpContainer = this; return true; } template //bool CH3DContainer<_obj>::Release( H3D_FILE_UID hf ) bool CH3DContainer<_obj>::Release( Z3DTOK hf ) { std::map::iterator it; //std::map::iterator it; //ppuchuu::map::iterator it; it = m_mapContainerElement.find( hf ); if( m_mapContainerElement.end() == it ) { return false; // no proper handle } --(it->second.lRefCount); if( 0 == it->second.lRefCount ) { SAFE_DELETE( it->second.pObj ); m_mapContainerElement.erase( it ); } return true; } template CH3DContainer<_obj>::~CH3DContainer() { SAFE_DELETEA( m_szFilePath ); FlushAll(); } template void CH3DContainer<_obj>::FlushAll() { std::map::iterator it; //std::map::iterator it; //ppuchuu::map::iterator it; for( it = m_mapContainerElement.begin(); it != m_mapContainerElement.end(); it++ ) { SAFE_DELETE( it->second.pObj ); } } template bool CH3DContainer<_obj>::PreLoadAll( const char* szFileSpec ) { SimpleString strFullPath( m_szFilePath, szFileSpec ); char* szFileNamePart; H3DContainerTag<_obj> tag; _finddata_t fileinfo; long lFindHandle = _findfirst( strFullPath, &fileinfo ); if( -1 == lFindHandle ) { return false; } do { szFileNamePart = strrchr( fileinfo.name, '\\' ); if( NULL == szFileNamePart ) { szFileNamePart = fileinfo.name; } else { ++szFileNamePart; } GetObject( tag, szFileNamePart ); } while( 0 == _findnext( lFindHandle, &fileinfo ) ); _findclose( lFindHandle ); return true; } #endif // !defined(AFX_H3DCONTAINER_H__EFFCAF0D_E084_4326_8D7C_BD0CAF16EB34__INCLUDED_)