转 一个在cocos2d-x上用curl 下载数据功能

来源:互联网 发布:bl网络电视剧 编辑:程序博客网 时间:2024/05/16 07:10

CCNetwork - any suggestions and comments are welcome :)

Added by Steve Kimabout 1 month ago

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();    }}

Replies (3)

Comment

RE: CCNetwork - any suggestions and comments are welcome :) - Added byWalzer Wang about 1 month ago

It will be a very useful class.
My suggestions when reviewing the code.

1. char url[260]; is danger, especially you dont' check the length before strcpy( network->url, url ), stack will easily overflow. I prefer to use std::string here to make it safe.

2. You like to use several return points in a function. It's not good when you would like to write some profile and test the performance. For example:


 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;        }

The recommended approach is

 static size_t writer( char *data, size_t size, size_t nmemb, string *writerData )        {            // profile_start            size_t retValue = 0;            if(writerData != NULL)            {                  writerData->append(data, size * nmemb);                  retValue = size * nmemb;            }            // profile_end. You have only one return point now            return retValue;        }


原创粉丝点击