Recently I am porting an app to cocos2d-x which I made for android, ios, bada, and qnx.
And realized that there is no simple way to get json object asynchronously.
So here, I am posting a class I have made. Please give me a feedback if there are some errors. Thank you.
CCNetwork.h
#include "cocos2d.h"
#include "stdio.h"
#include "stdlib.h"
#include "curl.h"
#include "pthread.h"
#include "cJSON.h"
namespace cocos2d
{
class CCNetwork : public CCObject
{
SEL_CallFunc callback;
SelectorProtocol *target;
pthread_t threadInfo;
char url[260];
cJSON *cJSONResult;
CCNetwork()
{
cJSONResult = NULL;
}
protected:
static size_t writer( char *data, size_t size, size_t nmemb, string *writerData )
{
if(writerData == NULL)
return 0;
writerData->append(data, size * nmemb);
return size * nmemb;
}
public:
virtual ~CCNetwork()
{
if( cJSONResult != NULL )
{
freeResultJSON();
}
}
static void *run( void *arg )
{
CCNetwork *network = (CCNetwork *)arg;
CURL *curl;
CURLcode res;
int result = 1;
string buffer;
network->cJSONResult = NULL;
curl_global_init( CURL_GLOBAL_ALL );
curl = curl_easy_init();
if( curl )
{
curl_easy_setopt( curl, CURLOPT_URL, network->url );
curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1L );
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, CCNetwork::writer );
curl_easy_setopt( curl, CURLOPT_WRITEDATA, &buffer );
res = curl_easy_perform( curl );
curl_easy_cleanup( curl );
if (res == 0)
{
network->cJSONResult = cJSON_Parse( buffer.c_str() );
if( network->cJSONResult != NULL )
result = 0;
}
}
((network->target)->*(network->callback))();
return (void *)result;
}
cJSON *getResultJSON()
{
int success;
if( pthread_join( threadInfo, (void **)&success ) == 0 )
return cJSONResult;
else
return NULL;
}
void freeResultJSON()
{
if( cJSONResult != NULL )
{
cJSON_Delete( cJSONResult );
cJSONResult = NULL;
}
}
static CCNetwork *loadJSON( const char *url, SelectorProtocol *target, SEL_CallFunc callback )
{
CCNetwork *network = new CCNetwork();
if( network != NULL )
{
network->target = target;
network->callback = callback;
strcpy( network->url, url );
if( pthread_create( &network->threadInfo, NULL, CCNetwork::run, network ) == 0 )
{
network->autorelease();
return network;
}
CC_SAFE_DELETE( network );
}
return NULL;
}
};
}
callback function
void dataArrived() { isThreadRunning = false; }
the part which request url
isThreadRunning = true;
scheduleUpdate();
network = CCNetwork::loadJSON( "http://dodgemissile2.appspot.com/?count=10", this, callfunc_selector( YourNode::dataArrived ) );
network->retain();
update function
void YourNode::update( ccTime dt )
{
if( !isThreadRunning )
{
if( network != NULL )
{
cJSON *result = network->getResultJSON();
// process with result here
network->release();
}
unscheduleUpdate();
}
}