您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx 3.6源码分析之文件路径

2015-08-11 16:56 281 查看
cocos2dx中资源文件都放在Resources目录中,编译后会自动复制到exe所在的目录中。

核心类是FileUtils类,一个单例类。

三个重要的函数

void addSearchPath(const std::string & path, const bool front=false);
virtual void addSearchResolutionsOrder(const std::string &order,const bool front=false);
virtual std::string fullPathForFilename(const std::string &filename) const;


依次分析。

void FileUtils::addSearchPath(const std::string &searchpath,const bool front)
{
std::string prefix;
if (!isAbsolutePath(searchpath))
prefix = _defaultResRootPath;

std::string path = prefix + searchpath;
if (path.length() > 0 && path[path.length()-1] != '/')
{
path += "/";
}
if (front) {
_searchPathArray.insert(_searchPathArray.begin(), path);
} else {
_searchPathArray.push_back(path);
}
}


核心数据成员_searchPathArray,首先判断是否是绝对路径,如果不是则通过平台相关的默认资源根路径得到前缀prefix。其次判断给定的字符串后有没有/,没有则加上。

第二个参数font代表搜索优先级,有优先级则插入到_searchPathArray的前端,否则放入后面。vector用Insert感觉还挺奇怪的。

void FileUtils::addSearchResolutionsOrder(const std::string &order,const bool front)
{
std::string resOrder = order;
if (!resOrder.empty() && resOrder[resOrder.length()-1] != '/')
resOrder.append("/");

if (front) {
_searchResolutionsOrderArray.insert(_searchResolutionsOrderArray.begin(), resOrder);
} else {
_searchResolutionsOrderArray.push_back(resOrder);
}
}


核心数据成员_searchResolutionsOrderArray,这里我理解为子目录,Resolutions这命名用在这里让我十分费解。同样如果传入字符串尾部没有/则加/。如果有优先级顺序则加入都头部,否则尾部。

下面就是重头戏了,查找路径的时候如何拼接目录和子目录为一个字符串。

std::string FileUtils::fullPathForFilename(const std::string &filename) const
{
if (filename.empty())
{
return "";
}

if (isAbsolutePath(filename))
{
return filename;
}

// Already Cached ?
auto cacheIter = _fullPathCache.find(filename);
if(cacheIter != _fullPathCache.end())
{
return cacheIter->second;
}

// Get the new file name.
const std::string newFilename( getNewFilename(filename) );

std::string fullpath;

for (const auto& searchIt : _searchPathArray)
{
for (const auto& resolutionIt : _searchResolutionsOrderArray)
{
fullpath = this->getPathForFilename(newFilename, resolutionIt, searchIt);

if (fullpath.length() > 0)
{
// Using the filename passed in as key.
_fullPathCache.insert(std::make_pair(filename, fullpath));
return fullpath;
}

}
}

if(isPopupNotify()){
CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", filename.c_str());
}

// The file wasn't found, return empty string.
return "";
}


这段代码思路,就是传入一个文件名,如何在资源路径中找到绝对路径的全名出来。这里就要用到之前的搜索路径和子路径了。

首先判断是否为空和是否为绝对路径,以"/"开头被认为是绝对路径则直接返回。然后再看有没有再文件缓存里面如果有则直接返回。

如果都没有则开始拼接一个新的绝对路径出来。这里就用到了前面添加的2个重要的数据成员_searchPathArray和_searchResolutionsOrderArray。

首先对_searchPathArray进行遍历,在每一个_searchPathArray成员中再对_searchResolutionsOrderArray进行遍历。

然后进入核心拼接函数。

std::string FileUtils::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) const
{
std::string file = filename;
std::string file_path = "";
size_t pos = filename.find_last_of("/");
if (pos != std::string::npos)
{
file_path = filename.substr(0, pos+1);
file = filename.substr(pos+1);
}

// searchPath + file_path + resourceDirectory
std::string path = searchPath;
path += file_path;
path += resolutionDirectory;

path = getFullPathForDirectoryAndFilename(path, file);

//CCLOG("getPathForFilename, fullPath = %s", path.c_str());
return path;
}


找到最后一个"/"出现的位置,如果filename字符串中没有"/",则Path = searchPath + resolutionDirectory,这里path只是文件夹路径,所以searchPath和resolutionDirectory也可以是多级目录路径。

getFullPathForDirectoryAndFilename会把目录路径和文件路径拼接起来。最后得到一个完整的path。

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: