分析cocos2d-x是如何异步的去加载图片

使用cocos2d-x的人应该都知道CCTextureCache类中有个异步加载图片的方法addImageAsync,也都知道其背后的实现原理肯定是基于多线程实现的,那么其背后的具体实现逻辑具体是怎样的,所以就带着好奇心的去把它研究了下:

先看addImageAsync的实现:

void CCTextureCache::addImageAsync(const char *path, CCObject *target, SEL_CallFuncO selector)
{
#ifdef EMSCRIPTEN//在2.2.2的版本中,不能通过脚本语言(lua和js)异步加载图片(听说qiuck-cocos2d-x实现了用脚本来异步加载图片)
    CCLOGWARN("Cannot load image %s asynchronously in Emscripten builds.", path);
    return;
#endif // EMSCRIPTEN

    CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL");//要加载的图片的路径不能为空

    CCTexture2D *texture = NULL;

    // optimization

    std::string pathKey = path;//创建字符串pathKey做为字典查询关键字。

    pathKey = CCFileUtils::sharedFileUtils()->fullPathForFilename(pathKey.c_str());//取得图片所在位置的全路径名 ,充当字典中的key

    texture = (CCTexture2D*)m_pTextures->objectForKey(pathKey.c_str());//先查询一下是否字典里已经有了此纹理。

    std::string fullpath = pathKey;//图片所在位置的全路径名


    if (texture != NULL)//如果字典存在该纹理图片,则不需要异步加载,直接执行回调函数
    {
        if (target && selector)
        {
            (target->*selector)(texture);//执行回调,将纹理作为参数传入
        }
        
        return;
    }


    // lazy init
    if (s_pAsyncStructQueue == NULL)//如果是第一次调用多线程载入,创建信号量并进行相应初始化。
    {             
        s_pAsyncStructQueue = new queue<AsyncStruct*>();//创建一个存储异步信息队列
        s_pImageQueue = new queue<ImageInfo*>();        //创建一个存储图片信息队列
        //线程锁初始化
        pthread_mutex_init(&s_asyncStructQueueMutex, NULL);
        pthread_mutex_init(&s_ImageInfoMutex, NULL);
        pthread_mutex_init(&s_SleepMutex, NULL);
        pthread_cond_init(&s_SleepCondition, NULL);
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
        pthread_create(&s_loadingThread, NULL, loadImage, NULL); //创建加载线程。
#endif
        need_quit = false; //将退出指令设为false。
    }

    if (0 == s_nAsyncRefCount)//多线程加载图片的引用计数器如果为0,
    {//用定时器处理异步加载图片(注意:其中的第三个参数为0,也就意味着这个定时器每帧都会被调用,也就是每帧都会调用一次addImageAsy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值