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布局 , 改动 ...
随机推荐
- Lunix含Ubuntu使用总结
错误 鼠标闪烁解决 系统设置->显示—>未知显示器->关闭->应用->选择当前配置 提示sudo: unable to resolve host ,亦即无法解析主机. 原 ...
- day4 递归二分法查找
现有一个序列,data=[for i in range(1,5000,3)],现在要求看一个数是否在列表中存在,我们知道,我们可以使用in或__contains__()的方法,判断一个值是否在列表中, ...
- mean(bootstrap,angular,express,node,mongodb)通用后台框架
学习node,我这个毫无美感的程序员在bootstrap与node的感染下,向着“全栈工程师”迈进,呵呵! 最终选择如题的技术方案,这些东东都算比较新的,网上的资料比较少,参考了不少github程序及 ...
- LoadRunner中参数的设置
LoadRunner中参数的设置 参数个数:10个 tester1.tester2.tester3…tester10 迭代次数:2次 场景设置(一):Sequential+Each Iteration ...
- spring完成自动装配
让spring完成自动装配 Autowiring 解决标签为javaBean注入时难以维护而实现的 下面是几种autowire type的说明: 1,byname:试图在容器中寻找和需要自动装配的属性 ...
- cloudstack ssvm 管理地址不够造成无法启动修复过程
cloudstack日志记录: 上面已经提示了,管理ip没有了,造成这个原因很多,遇到过ssvm非正常关闭就有可能不释放IP慢慢把IP消耗掉.总之这肯定是BUG.按照上面的提示找到对应pod 和dc ...
- Ubuntu下查看软件版本及安装位置
查看软件版本: XXX --version 或 aptitude show xxx 也可用apt-show-versions (要先安装sudo apt-get install apt-show-ve ...
- appengine 云计算。 部署web网络。
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha appengine 可以 不用手动启动像服务器. 在eclipse中 这两个sdk 配好 ...
- android studio 继续汉化 编译项目 菜单
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha Edit Flavors...
- Codeforces 980 D. Perfect Groups
\(>Codeforces\space980 D. Perfect Groups<\) 题目大意 : 设 \(F(S)\) 表示在集合\(S\)中把元素划分成若干组,使得每组内元素两两相乘 ...