自己的引擎里做了个简单的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生成了带../的路径目前我也不知道。

最新文章

  1. python画图设置坐标轴大小
  2. 【小贴士】虚拟键盘与fixed带给移动端的痛!
  3. WAMP2.5 Forbidden
  4. 线程变量ThreadLocal的使用
  5. Codeforces Round #382 (Div. 2) A. Ostap and Grasshopper bfs
  6. bootstrap插件学习-bootstrap.carousel.js
  7. 解决 mysql 启动报错--发现系统错误2,系统找不到指定的文件
  8. MapReduce框架Partitioner分区方法
  9. FPGA中如何实现除法?
  10. Part 33 Difference between abstract classes and interfaces
  11. Oracle中使用escape关键字实现like匹配特殊字符,以及&字符的转义
  12. lex&amp;yacc2
  13. Time_wait问题小结
  14. spdlog源码阅读 (3): log_msg和BasicWriter
  15. 一小时学会ECMAScript6新特性
  16. redis分布式锁-SETNX实现
  17. CSS常见兼容问题以及解决办法
  18. 华为S5700配置端口镜像和华三S5120配置802.1X认证记录
  19. ix 混合索引
  20. [转]Oracle存储过程总结

热门文章

  1. (转)unity3d中脚本生命周期(MonoBehaviour lifecycle)
  2. 我所认识的PCA算法的princomp函数与经历 (基于matlab)
  3. Java HashMap 默认排序
  4. 输入框提示文字跨浏览器的placeholder-jQuery版
  5. hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载
  6. YII插件
  7. 如何不使用pthread_cancel而杀死线程
  8. [转]自定义Drawable实现灵动的红鲤鱼动画(下篇)
  9. 算法笔记_110:第四届蓝桥杯软件类省赛真题(JAVA软件开发高职高专组部分习题)试题解答
  10. Simple example