zoukankan      html  css  js  c++  java
  • cocos2dx 3.6源码分析之文件路径

    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。

      

  • 相关阅读:
    *setTimeout实现text输入在用户停顿时才调用事件!*
    *关于TextArea里中英文混合时换行的问题*
    *用C#创建Windows服务(Windows Services)
    *使用C# 创建邮件发送组件(SMTP)
    *ASP.NET 2.0 连接SQL Server数据库详解
    *SQL2000系统表的应用
    *在.NET(正式版)环境下发送邮件
    *如何解决select等元素突出来的问题
    *介绍JSON*
    Tomcat性能配置
  • 原文地址:https://www.cnblogs.com/beyond-time-space/p/4721512.html
Copyright © 2011-2022 走看看