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布局 , 改动 ...
随机推荐
- Adding Completion to (interactive)
Adding Completion to (interactive) Author: Tubo Question: Is there any way to add my own completio ...
- MVC – 5.MVC设计模式和.NetMVC框架
MVC模式-设计模式 •控制器(Controller)- 负责转发请求,对请求进行处理. •视图 (View) - 界面设计人员进行图形界面设计. •模型 (Model)-业务逻辑.数据.验证规则.数 ...
- 783. Minimum Distance Between BST Nodes
Given a Binary Search Tree (BST) with the root node root, return the minimum difference between the ...
- Java学习(简介,软件安装)
1. Java概述: Java的发展可以归纳如下的几个阶段. (1)第一阶段(完善期):JDK 1.0 ( 1995年推出)一JDK 1.2 (1998年推出,Java更名为Java 2): (2)第 ...
- python开发学习-day05(正则深入、冒泡排序算法、自定义模块、常用标准模块)
s12-20160130-day05 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- ubuntu 系统提示升级失败,boot空间不足
系统提示升级失败,boot空间不足,解决方法: linux 随着系统的升级,会自动攒下好几个内核 执行 uname -a 看下自己当前启动的是哪个内核 dpkg --get-selections |g ...
- logstash通过redis收集日志
(1)部署redis 1丶安装redis yum install epel-release -y yum install redis -y 2丶修改配置文件 #vim /etc/redis.conf ...
- 20169211《Linux内核原理与分析》第一周作业
本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没 ...
- office2016破解激活安装
昨天一室友装office2016不会激活,[嘲讽脸]真的是笨啊.我这是在一个社区论坛里面找到的. 在网上找了教程,有些没用的,所以记录安装教程以便之后查看.以下的安装激活亲测有效(2017-4-28) ...
- Mock(模拟后端接口数据)配合Vuex的使用
1.下载Mock cnpm install Mockjs -S 2.新建一个data.js存放新生成的mock文件 编辑mock 并导出 const Mock = require('mockjs' ...