Cocos2d-x3.2 TextureCache类异步加载功能讲解

Cocos2d-x3.2 TextureCache类异步加载功能讲解,第1张

概述本文TextureCache类异步加载功能的代码抽出,总共代码就200多行,感兴趣可以看看。 研究这个主要是因为项目中需要异步插入数据,但之前的方法在Android上总是崩溃所以想到TextureCache有异步加载的功能就将其抽出了。 原文地址:http://blog.csdn.net/qqmcy/article/details/39890837 代码下载:http://download.csd

本文TextureCache类异步加载功能的代码抽出,总共代码就200多行,感兴趣可以看看。

研究这个主要是因为项目中需要异步插入数据,但之前的方法在AndroID上总是崩溃所以想到TextureCache有异步加载的功能就将其抽出了。

原文地址:http://blog.csdn.net/qqmcy/article/details/39890837

代码下载:http://download.csdn.net/detail/qqmcy/8011589


首先,创建AsyncTasktime类,主要模拟一个费时的方法

AsyncTasktime.h

#include "cocos2d.h"USING_NS_CC;class AsyncTasktime{public:        //模拟一个费时 *** 作    bool initWithImagefileThreadSafe(const std::string &filename);        };

AsyncTasktime.cpp

////  AsyncTasktime.cpp//  cpp4////  Created by 杜甲 on 10/8/14.////#include "AsyncTasktime.h"bool AsyncTasktime::initWithImagefileThreadSafe(const std::string &filename){    std::this_thread::sleep_for(std::chrono::milliseconds(3000));    return true;}

创建异步加载功能类

asynctest.h

////  asynctest.h//  cpp4////  Created by 杜甲 on 10/8/14.////#ifndef __cpp4__asynctest__#define __cpp4__asynctest__#include "cocos2d.h"#include "AsyncTasktime.h"using namespace std;USING_NS_CC;class asynctest : public Ref{public:    CREATE_FUNC(asynctest);        virtual bool init();        asynctest();        // 异步加载    voID addImageAsync(const string &path,const function<voID(AsyncTasktime *)> &callback);private:        voID addImageAsyncCallback(float dt);    //加载数据    voID loadImage();    public:    struct AsyncStruct    {    public:        AsyncStruct(const string &fn,function<voID(AsyncTasktime *)> f): filename(fn),callback(f){};                string filename;        function<voID(AsyncTasktime *)> callback;    };    protected:        typedef struct    {        AsyncStruct *asyncStruct;        AsyncTasktime *image;    }ImageInfo;            thread *_loadingThread;    queue<AsyncStruct *>        *_asyncStructQueue;    deque<ImageInfo *>          *_ImageInfoQueue;        mutex                       _asyncStructQueueMutex;    mutex                       _imageInfoMutex;        mutex                       _sleepMutex;    condition_variable          _sleepCondition;        bool                        _needQuit;    int                         _asyncRefCount;    unordered_map<std::string,AsyncTasktime* > _textures;                };#endif /* defined(__cpp4__asynctest__) */

asynctest.cpp

////  asynctest.cpp//  cpp4////  Created by 杜甲 on 10/8/14.////#include "asynctest.h"asynctest::asynctest(): _loadingThread(nullptr),_asyncStructQueue(nullptr),_ImageInfoQueue(nullptr),_needQuit(false),_asyncRefCount(0){    }bool asynctest::init(){    return true;}voID asynctest::addImageAsync(const string &path,const function<voID (AsyncTasktime *)> &callback){    AsyncTasktime *texture = nullptr;        auto it = _textures.find(path);    if (it != _textures.end()) {        texture = it->second;    }        if (texture != nullptr) {        callback(texture);        return;    }        if (_asyncStructQueue == nullptr) {        _asyncStructQueue = new queue<AsyncStruct *>();        _ImageInfoQueue = new deque<ImageInfo *>();                _loadingThread = new thread(&asynctest::loadImage,this);                _needQuit = false;    }        if (0 == _asyncRefCount) {        Director::getInstance()->getScheduler()->schedule(schedule_selector(asynctest::addImageAsyncCallback),this,false);    }        ++_asyncRefCount;        auto data = new AsyncStruct(path,callback);        _asyncStructQueueMutex.lock();    _asyncStructQueue->push(data);    _asyncStructQueueMutex.unlock();        _sleepCondition.notify_one(); //将等待 condition_variable 对象的其中一个线程解除阻塞。            }voID asynctest::loadImage(){    AsyncStruct *asyncStruct = nullptr;    while (true) {        queue<AsyncStruct *> *pQueue = _asyncStructQueue;        _asyncStructQueueMutex.lock();        if (pQueue->empty()) {                    }        else{            asyncStruct = pQueue->front();            pQueue->pop();            _asyncStructQueueMutex.unlock();        }                AsyncTasktime *image = nullptr;        bool generateImage = false;                auto it = _textures.find(asyncStruct->filename);        if (it == _textures.end()) {            _imageInfoMutex.lock();            ImageInfo *imageInfo;            size_t pos = 0;            size_t infoSize = _ImageInfoQueue->size();            for (; pos < infoSize; pos++) {                imageInfo = (*_ImageInfoQueue)[pos];                if (imageInfo->asyncStruct->filename.compare(asyncStruct->filename) == 0)                    break;                            }            _imageInfoMutex.unlock();            if (infoSize == 0 || pos == infoSize)                generateImage = true;                    }                if (generateImage) {            const string &filename = asyncStruct->filename;            image = new AsyncTasktime();            if (image && !image->initWithImagefileThreadSafe(filename)) {                continue;            }        }                auto imageInfo = new ImageInfo();        imageInfo->asyncStruct = asyncStruct;        imageInfo->image = image;                _imageInfoMutex.lock();        _ImageInfoQueue->push_back(imageInfo);        _imageInfoMutex.unlock();            }        if (_asyncStructQueue != nullptr) {        delete _asyncStructQueue;        _asyncStructQueue = nullptr;        delete _ImageInfoQueue;        _ImageInfoQueue = nullptr;    }    }voID asynctest::addImageAsyncCallback(float dt){    deque<ImageInfo *> *imagesQueue = _ImageInfoQueue;    _imageInfoMutex.lock();    if (imagesQueue->empty()) {        _imageInfoMutex.unlock();    }    else{        auto imageInfo = imagesQueue->front();        imagesQueue->pop_front();        _imageInfoMutex.unlock();                auto asyncStruct = imageInfo->asyncStruct;        auto image = imageInfo->image;        if (asyncStruct->callback) {            asyncStruct->callback(image);        }                --_asyncRefCount;        if (0 == _asyncRefCount) {            Director::getInstance()->getScheduler()->unschedule(schedule_selector(asynctest::addImageAsyncCallback),this);        }    }}


调用:

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"#include "asynctest.h"USING_NS_CC;class HelloWorld : public cocos2d::Layer{public:    // Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'ID' in cocos2d-iphone        HelloWorld();        virtual bool init();      // there's no 'ID' in cpp,so we recommend returning the class instance pointer    static cocos2d::Scene* scene();               // implement the "static node()" method manually    CREATE_FUNC(HelloWorld);        private:    Size winSize;    //这里添加一个回调方法    voID loadCallback1(AsyncTasktime *time);    };#endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

// on "init" you need to initialize your instancebool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !Layer::init() )    {        return false;    }        auto as = asynctest::create();    as->retain();    as->addImageAsync("test",CC_CALLBACK_1(HelloWorld::loadCallback1,this));                       return true;}voID HelloWorld::loadCallback1(AsyncTasktime *time){        log("加载完成");    }


控制台:

cocos2d: 加载完成


这样我们就将TextureCache中

virtual voID addImageAsync(conststd::string &filepath,const std::function<voID(Texture2D*)>& callback);

这个异步加载数据的功能实现了。 总结

以上是内存溢出为你收集整理的Cocos2d-x3.2 TextureCache类异步加载功能讲解全部内容,希望文章能够帮你解决Cocos2d-x3.2 TextureCache类异步加载功能讲解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1001672.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存