自己的引擎里做了个简单的TextueCache,每次新创建一个纹理,先到TextureCache里查找有没有路径相同的,如果有就直接返回纹理,如果没有加载图片创建纹理并将图片路径缓存起来。另外为了标准统一,我们可以规定路径都转化成全路径(full path)再缓存。

不过发现对于使用了返回父级符号 ../ 的路径,这样简单处理是有问题的,比如 a/b/../x.png 和 a/c/../x.png 这两个路径,形式上不同,实际上却是等价。为了解决这个问题,在做两个全路径比较时要先将两个全路径都转成不带 ../ 符号的形式再比较。下面代码可用于临时解决问题但未必完善:

   bool isPathEqual(const string&fullPath1,const string&fullPath2){//fullPath1 and fullPath2 must be full path

string path1=convertToDirectPath(fullPath1);

string path2=convertToDirectPath(fullPath2);

const int path1Len=(int)path1.size();

const int path2Len=(int)path2.size();

if(path1Len!=path2Len)return false;

for(int i=0;i<path1Len;i++){

if(path1[i]=='/'||path1[i]=='\\'){

if(path2[i]=='/'||path2[i]=='\\'){

//ok

}else{

return false;

}

}else{

if(path1[i]!=path2[i])return false;

}

}

return true;

}

string convertToDirectPath(const string&path){//convert path to equivalent form without ../

string pathDirect;

for(int i=0;i<(int)path.size();i++){

if(i+3<(int)path.size()

&&(path[i]=='/'||path[i]=='\\')

&&path[i+1]=='.'

&&path[i+2]=='.'

&&(path[i+3]=='/'||path[i+3]=='\\'))

{

for(int j=(int)pathDirect.size()-1;j>=0;j--){

if(pathDirect[j]=='/'||pathDirect[j]=='\\'){

pathDirect.resize(j+1);

break;

}

}

i+=3;

assert(path[i]=='/'||path[i]=='\\');

}else{

pathDirect=pathDirect+path[i];

}

}//got pathDirect

return pathDirect;

}

当然,支持带../路径是一种选择,另一种选择是引擎直接规定根本不支持带../的路径,但若是如此则一定要对于用户传进来的路径进行检查,如果发现其中带有/../或者开头是../,则给出一个assert fail中断和错误提示,否则既接受带../的输入,又暗自里将纹理加载N次,就坑了。

不知道cocos2dx里的TextureCache有没有考虑这种情况,等有时间看下。

更新(2015-4-9):

刚才测试了一下,cocos2dx不会识别等价路径:

TextureCache::getInstance()->addImage("res/a.png");
Texture2D*tex=TextureCache::getInstance()->getTextureForKey("res/b/../a.png");
cout<<"tex:"<<tex<<endl;
输出结果:
tex:0x0

因此,如果在cocos2dx里对纹理图片使用带../的路径是会悲剧的。

补充(2015-4-9):

还有一种藏得更深的悲剧情况,即可能你自己写的路径都不含../,但你用tiledmap生成的.tmx中却含有../,这一点极易忽视。我把公司的cocos2dx项目中的.tmx文件查看了一遍,发现里面还真有带../的路径,非常奇怪,多数路径都是不带../的,但却有个别带,是什么原因导致tiledmap生成了带../的路径目前我也不知道。

textureCache中的等价路径问题的更多相关文章

  1. Android中访问sdcard路径的几种方式

    以前的Android(4.1之前的版本)中,SDcard路径通过"/sdcard"或者"/mnt/sdcard"来表示,而在JellyBean(安卓4.1)系统 ...

  2. J2EE web项目中解决所有路径问题

    Java中使用的路径,分为两种:绝对路径和相对路径.归根结底,Java本质上只能使用绝对路径来寻找资源.所有的相对路径寻找资源的方法,都不过是一些便利方法.不过是API在底层帮助我们构建了绝对路径,从 ...

  3. Inno setup中定制安装路径

    我的程序修改了安装界面,所以我的界面中提供了更改安装路径的方法. 用户修改后的路径会被传回inno setup脚本,脚本中需要做的事情如下: 1,写一个函数,来返回新的安装路径,如: function ...

  4. web项目中,视图层中关于相对路径和绝对路径

    1.在jfinal项目中 因为一直使用的jfinal,没感觉路径问题. 举个栗子,项目名字叫做test.访问一个Controller的映射为/user/add.这样,在浏览器地址栏直接:localho ...

  5. servlet中的相对路径和绝对路径 及/, ./, ../的区别

    ./ 当前目录../ 父级目录/ 根目录资源寻找都是依靠路径,资源存储方式是按照哈希表运算的,所以路径的计算其实就是哈希值的计算. servlet中,所有路径的配置都要用绝对路径. 什么是绝对路径,就 ...

  6. java web项目中 获取resource路径下的文件路径

    public GetResource{ String path = GetResource.class.getClassLoader().getResource("xx/xx.txt&quo ...

  7. php读取出字符串中的img标签中的图片路径

    php读取出字符串中的img标签中的图片路径 $pageContents = '字符串,带img标签'; $pageContents = str_replace('\"','"', ...

  8. java工程中的相关路径

    一.路径 绝对路径: 指的是文件在系统中的真实路径(物理路径). 相对路径: 指的是文件相对某个目录的相对路径. 对于java application 工程来说,当编写完一个类之后,class文件会编 ...

  9. 【转】JSP中的相对路径和绝对路径

    1.首先明确两个概念: 服务器路径:形如:http://192.168.0.1/的路径 Web应用路径:形如:http://192.168.0.1/yourwebapp的路径 2.关于相对路径与绝对路 ...

随机推荐

  1. 【HTML5】实现QQ聊天气泡效果

    今天自己用 HTML/CSS 做了个类似QQ的聊天气泡,以下是效果图: 以下说下关键地方的样式设置.然后贴出html和css代码(不多). 步骤1:布局 消息採用div+float布局,每条消息用一个 ...

  2. shell中如何取括号中的字符

    1. 使用grep(结果带括号,不知道有没有办法仅把括号中的内容匹配出来) $a='abc[edg]adfirpqu' $echo $a|grep -o '\[.*\]' #中括号的处理需要转义 [e ...

  3. jsp中的js嵌入Extjs与后台action交互

    近期做前台须要和后台交互数据,直接使用js一直没实现.最后使用extjs实现了,extjs代码直接嵌入到jsp的js代码中就可以(0跟jsp里使用extjs一样,须要载入extjs的几个文件) < ...

  4. SVN diff 笔记

    SVN diff命令在实际中经常使用,在此记录使用点滴. #对比工作文件与缓存在.svn的“原始”拷贝: svn diff #显示工作文件和服务器版本2的不同: svn diff -r 2 #显示分支 ...

  5. CSS实现水平垂直居中方式

    1.定位 核心代码实现请看示例代码中的注释: <!DOCTYPE html> <html lang="zh"> <head> <meta ...

  6. Java 基础【12】 日期类型

    java api中日期类型的继承关系 java.lang.Object --java.util.Date --java.sql.Date --java.sql.Time --java.sql.Time ...

  7. 怎样让CodeBlocks支持C99

    转载请注明出处,否则将追究法律责任http://blog.csdn.net/xingjiarong/article/details/47080303 CodeBlocks是一个写C/C++的比較好的编 ...

  8. DB2的认证和授权

    DB2 的安全性由两方面组成:认证和授权 1.认证 认证就是系统验证用户身份的过程.说的简单点,就是验证用户名和密码,因为DB2用户同时也是操作系统用户,所以,首先必须得到操作系统的认可.在默认情况下 ...

  9. Python之os.walk()

    #http://www.cnblogs.com/bluescorpio/archive/2009/10/21/1587493.html os.walk() 返回结果:可以得到一个(dirpath, d ...

  10. CEF 各个版本适应的平台参考表

    This Wiki page provides information about CEF branches and instructions for downloading, building an ...