菜鸟学习OGRE和天龙八部之十八: 获得档案(Archive)文件列表

来源:互联网 发布:jenkins java home 编辑:程序博客网 时间:2024/05/02 01:46

要获得档案文件的文件列表,只要获得Archive的指针,就可以调用list()函数获得文件列表

 

但是如何获得Archive的指针呢,先看看资源的载入过程:

 

先从resources.cfg文件获取资源的路径,资源组,资源文件类型,这3个数据:

 ConfigFile cf;
 cf.load("resources.cfg");

 

再把这3个数据传入资源定位的函数:

ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);

资源定位到底做了什么,看看源码:

view plain
  1.   void ResourceGroupManager::addResourceLocation(const String& name,   
  2.       const String& locType, const String& resGroup, bool recursive)  
  3.   {  
  4.       ResourceGroup* grp = getResourceGroup(resGroup);  
  5.       if (!grp)  
  6.       {  
  7.           createResourceGroup(resGroup);  
  8.           grp = getResourceGroup(resGroup);  
  9.       }  
  10.   
  11. OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex  
  12.   
  13.       // Get archive  
  14.       Archive* pArch = ArchiveManager::getSingleton().load( name, locType );  
  15.       // Add to location list  
  16. ResourceLocation* loc = new ResourceLocation();  
  17. loc->archive = pArch;  
  18. loc->recursive = recursive;  
  19.       grp->locationList.push_back(loc);  
  20.       // Index resources  
  21.       StringVectorPtr vec = pArch->find("*", recursive);  
  22.       for( StringVector::iterator it = vec->begin(); it != vec->end(); ++it )  
  23.       {  
  24.     // Index under full name, case sensitive  
  25.           grp->resourceIndexCaseSensitive[(*it)] = pArch;  
  26.           if (!pArch->isCaseSensitive())  
  27.           {  
  28.            // Index under lower case name too for case insensitive match  
  29.             String indexName = (*it);  
  30.               StringUtil::toLowerCase(indexName);  
  31.            grp->resourceIndexCaseInsensitive[indexName] = pArch;  
  32.           }  
  33.       }  
  34.   
  35. StringUtil::StrStreamType msg;  
  36. msg << "Added resource location '" << name << "' of type '" << locType  
  37.     << "' to resource group '" << resGroup << "'";  
  38. if (recursive)  
  39.     msg << " with recursive option";  
  40. LogManager::getSingleton().logMessage(msg.str());  
  41.   
  42.   }  

 

我们可以看到

        // Get archive
        Archive* pArch = ArchiveManager::getSingleton().load( name, locType );

这里,载入档案的时候就返回了档案的指针,这就是我们需要的,接下来他把这个指针传到了2个地方

        // Add to location list
  ResourceLocation* loc = new ResourceLocation();
  loc->archive = pArch;  // 这里传入一次

 

   // Index under full name, case sensitive
            grp->resourceIndexCaseSensitive[(*it)] = pArch;  // 这里再传入一次

 

理论上我们可以从这2个数据结构中获取指针,但是不幸的是,这些都是protected成员,获取不了的

而这个类又没有提供相关的获取函数,怎么办呢?难道又要改OGRE源码么?

 

看看前面的这个函数

        // Get archive
        Archive* pArch = ArchiveManager::getSingleton().load( name, locType );

如果已经载入了一次,我们再载入一次,会发现什么情况

view plain
  1. Archive* ArchiveManager::load( const String& filename, const String& archiveType)  
  2. {  
  3.     ArchiveMap::iterator i = mArchives.find(filename);  
  4.     Archive* pArch = 0;  
  5.   
  6.     if (i == mArchives.end())  
  7.     {  
  8.         // Search factories  
  9.         ArchiveFactoryMap::iterator it = mArchFactories.find(archiveType);  
  10.         if (it == mArchFactories.end())  
  11.             // Factory not found  
  12.             OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find an archive factory "  
  13.                 "to deal with archive of type " + archiveType, "ArchiveManager::load");  
  14.   
  15.         pArch = it->second->createInstance(filename);  
  16.         pArch->load();  
  17.         mArchives[filename] = pArch;  
  18.   
  19.     }  
  20.     else  
  21.     {  
  22.         pArch = i->second;  
  23.     }  
  24.     return pArch;  
  25. }  

 

看了源码,豁然开朗!!!

原来载入档案的时候,他会先查看这个档案资源已经载入了没有,如果已经载入了,直接返回这个档案资源的指针!!!

 

所以我们在外部再载入一次,就可以获得这个资源的指针:

view plain
  1. // 获得地图列表文件  
  2. TLBBArchive* arch = (TLBBArchive*)ArchiveManager::getSingleton().load("../../Data/Scene.axp""AxpPack");  
  3. mMaplistPtr = arch->list();  

 

到此,就已经获得了列表文件信息,

用MFC对话框打开看看:

view plain
  1. BOOL COpenMapDlg::OnInitDialog()       
  2. {     
  3.     CDialog::OnInitDialog();     
  4.   
  5.     // 获得地图列表  
  6.     CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST1);  
  7.   
  8.     CTLBBView* view = (CTLBBView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView(); // 获得视图类  
  9.     StringVectorPtr svPtr = view->getOgreApp()->getMaplistPtr();  
  10.   
  11.     vector<String>::iterator iter = svPtr->begin();  
  12.     for (; iter != svPtr->end(); ++ iter)  
  13.     {  
  14.         String str = *iter;  
  15.         if (StringUtil::endsWith(str, ".Scene"false))  
  16.         {  
  17.             pListBox->AddString(str.c_str());  
  18.         }     
  19.     }  
  20.   
  21.     return   TRUE;         
  22. }   

 

最后效果:


原创粉丝点击