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布局 , 改动 ...
随机推荐
- 洛谷P2692 覆盖 题解
题目传送门 这道题一开始想使用二维的bool型数组来存,最后统计.但看到数据范围... 所以就改用两个bool型数组(一维),分别储存横.列,最后将横.列面积求出来,再减去重复算的面积(横的个数*列的 ...
- Jmeter-----保存到响应文件
在jmeter中使用保存响应到文件 ------适用于非GUI模式执行脚本时,无法查看报错的信息. 1.添加组件: 2.各个配置项说明: 1.名称:即组件在整个测试计划中的名称显示,建议设置为用意义的 ...
- Android Webview中解决H5的音视频不能自动播放的问题
在开发webview的时候,当加载有声音的网页的时候,声音不会自动播放, 解决方法:在webview中调用js方法.这个方法需要在webview的setWebViewClient方法之后在onPage ...
- linux中忘记root密码解决方案
方法一: 如果用户具有sudo权限,那么直接可以运行如下命令: #sudo su root #passwd #更改密码 或者直接运行sudo passwd root命令就可以直接更改root密码. 有 ...
- LoadRunner监控Linux资源
一.LoadRunner监控Linux资源 (一).准备工作 首先,监视Linux一定要有rstatd这个守护进程,有的Linux版本里也有可能是rpc.rstatd这里只是名字不同而已,功能是一样的 ...
- iOS 9音频应用播放音频之iOS 9音频播放进度
iOS 9音频应用播放音频之iOS 9音频播放进度 iOS 9音频应用开发播放进度 音频文件在播放后经过了多久以及还有多久才可以播放完毕,想必是用户所关注的问题.为了解决这一问题,在很多的音乐播放器中 ...
- 基础数据类型汇总补充;集合set ;深浅copy
首先回顾: 小数据池:int -5~256str 特殊字符,*数字20 ascii : 8位 1字节 表示1个字符unicode 32位 4个字节 表示一个字符utf- 8 1个英文 8位,1个字节 ...
- Selenium之PhantomJS相关设置
设置PhantomJS请求头 默认情况下: from selenium import webdriver import time driver = webdriver.PhantomJS() driv ...
- [BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)
4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1313 Solved: 471[Submit][Stat ...
- Eclipse下mallet使用的方法
Mallet是Umass大牛开发的一个关于统计自然语言处理的l的开源库,很好的一个东西.可以用来学topic model,训练ME模型等.对于开发者来说,其官网的技术文档是非常有效的. mallet下 ...