Cocos2d-x3.2 TextureCache类异步载入功能解说
本文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, 0, 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 instance
bool 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类异步载入功能解说的更多相关文章
- cocos2dx3.2 异步载入和动态载入
半个月没有更新博客,从这个项目開始学习了非常多细节的东西,都不太成系统.可是却是开发上线中必须经历的东西.比方超级玛丽系列(一)中的正确的异步载入,正确的分层.正确的合成和载入plist.及时的移除未 ...
- Mvc音乐商店demo的ajax异步删除功能总结
刚刚从学校出来参加工作,没啥工作经验,所以各位大神们不要嘲笑哈! 来公司后要进行培训,给我们的作业中有一个使用 dapper+mvc+ajax+SQL Server 2008,来实现一个音乐商店的de ...
- Android异步载入全解析之使用多线程
异步载入之使用多线程 初次尝试 异步.异步,事实上说白了就是多任务处理.也就是多线程执行.多线程那就会有各种问题,我们一步步来看.首先.我们创建一个class--ImageLoaderWithoutC ...
- structs2注解+jsp+ajax实现post异步载入select
流程: 1.点击载入btn发起异步请求post 2.后台处理请求返回数据 3.前端获取数据成功,对数据进行处理 前端: html:首先要导入jq包,不然怎么用ajax呢. <script typ ...
- Android异步载入全解析之IntentService
Android异步载入全解析之IntentService 搞什么IntentService 前面我们说了那么多,异步处理都使用钦定的AsyncTask.再不济也使用的Thread,那么这个Intent ...
- PHP设计模式:类自动载入、PSR-0规范、链式操作、11种面向对象设计模式实现和使用、OOP的基本原则和自动加载配置
一.类自动载入 SPL函数 (standard php librarys) 类自动载入,尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_registe ...
- UE4异步载入资源
转自:http://blog.ch-wind.com/ue4%E5%BC%82%E6%AD%A5%E8%BD%BD%E5%85%A5%E8%B5%84%E6%BA%90/ 所有的“硬”指针指向的资源都 ...
- Android异步载入全解析之使用AsyncTask
Android异步载入全解析之使用AsyncTask 概述 既然前面提到了多线程,就不得不提到线程池,通过线程池,不仅能够对并发线程进行管理.更能够提高他们运行的效率.优化整个App.当然我们能够自己 ...
- ListView的异步载入(笔记,多线程和AsyncTask)
异步载入最经常使用的两种方式: 多线程,线程池 AsyncTask 实例操作: 从一个站点上获取Json数据.然后将数据在ListView上显示. 1.创建item_layout布局 , 改动 ...
随机推荐
- python爬取网易云音乐歌单音乐
在网易云音乐中第一页歌单的url:http://music.163.com/#/discover/playlist/ 依次第二页:http://music.163.com/#/discover/pla ...
- AndroidStudio升到最新版本(3.1.2)之后
暂时发现的需要大家注意的地方 1.androidstudio3无法导入moudle? 例如:我写了一个简单的项目,需要导入一个第三方的moudle,我导入: 因为AS升级之后,没有突出颜色的变化(变黑 ...
- [实战]MVC5+EF6+MySql企业网盘实战(13)——编辑文件夹
写在前面 上篇文章实现了,新建文件夹以及与之前的上传文件的逻辑做了集成,本篇文章将实现编辑文件夹名称,其实这个也有难点,就是编辑文件夹名称时,要考虑文件夹中存在文件或者子文件夹的情况,因为他们的路径已 ...
- 编译PHP并与Ngnix整合
nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端. nginx一般是把请求发fastcgi管理进程处理,fascgi管 ...
- GNU Wget 1.19.4 for Windows
资源地址:https://eternallybored.org/misc/wget/ 然后将工具目录加入环境变量
- [hdu3934] 凸包 旋转卡壳
大致题意: 求多边形的最大内接三角形 旋转卡壳 模板题 #include<cstdio> #include<iostream> #include<cstring> ...
- Python数据类型-元组
元组的基本操作: 获取元素个数:len() 连接两个元组:元组1 + 元组2 复制多个元组:元组 * 复制数量 获取单个元素:元组[索引位置] 获取多个元素:元组[起始位置:终止位置:间隔数量] 获取 ...
- TensorFlow——module 'tensorflow' has no attribute 'xxx'
tf.sub()更改为tf.subtract() tf.mul()更改为tf.multiply() tf.types.float32更改为tf.float32 tf.pact()更改为tf.stact ...
- SpringMVC框架 之 from标签(转)
原文地址:http://blog.csdn.net/kutim/article/details/46682547 spring表单标签 <%@taglib uri="http:// ...
- FastReport.Net使用:[6]HTML标签使用
使用HTML标签的基础知识 1.FastReport所支持的HTML标签包括: ●粗体:<b>...</b> ●斜体:<i>...</i> ●下划线:& ...