Search code examples
cocos2d-x

Sending Paramters to a CCCallFuncND::create Cocos2d-X


I have the following code in my Cocos2d-X application

void SampleRequest::setResponseCallback(CCCallFuncND* cb){
    if(cb){
        cb->retain();
        stored_cb=cb;
    }
}


void SampleRequest::executeStoredCallback(){
    if(stored_cb)
        stored_cb->execute();
}

void SampleRequest::releaseCallback(){
    if(stored_cb){
        stored_cb->release();
        stored_cb=NULL;
    }
}

and a simple class

void RequestHandler::handleSampleRequest(int data){
    CCLog("--------------------------------------------> Its here for me to do %d",data);
}

and another peace of code

    int i=10;
    SampleRequest *t=new SampleRequest();
    t->setResponseCallback(
                CCCallFuncND::create(
                this,
                callfuncND_selector(RequestHandler::handleSampleRequest),
                (void*)&i));

but the value of i recieved is 0. How can i send the value of I back to the call back function, and how can i send multiple parameters to this function.

Kind Regards,


Solution

  • int i=10;
    

    Are you declaring i as a temporary variable on the stack, rather than on the heap, or as request object instance data? If so, your i variable will be destroyed when the block within which it is created exits (variable scope ends).

    That could explain why the callback receives a value pointing to undefined memory, that has been destroyed at the time of the call.

    Try using the new operator, or storing your i value inside your request object up until the cb call is made.

    how can i send multiple parameters to this function

    You would not ; Simply pass a pointer to a structure or object. If all your stored data is in your "request" instance, you can pass the instance itself, as well.

    For an example, assuming, again, that the data passed to the callback is going to remain in memory at the time of the call to the callback function (ie, the "RequestData" instance below):

        struct RequestData
        {
          int value1 ;
          int value2 ;
          // ....
        } ;
    
       class RequestHandler: public cocos2d::CCObject
        {
           // ...
           public: 
             void requestCallback( CCNode* sender, void* pData ) ;
        }
    

    In your implementation:

    RequestHandler::requestCallback( CCNode* sender, void* pData ) 
    {
       RequestData* pRequestData = static_cast<RequestData*>( pData ) ;
    
      if ( pRequestData )
      {
         // do something ...
      }
    }
    

    To construct your call, build an instance of RequestData containing all the data you need to pass to the callback, make sure it is allocated on the heap with "new" or part of another object (in a queue, for instance) so that its data will still be valid in memory at the time the callback is called. I insist a bit on this point because you need some kind of data storage mechanism as part of your design, otherwise your callbacks may find themselves working off invalid addresses in memory (dangling pointers).

    Essentially, from your previous code:

    RequestData* pRequestData = new RequestData();
    // fill in the structure data here...
    
    SampleRequest *t=new SampleRequest();
    t->setResponseCallback(
                CCCallFuncND::create(
                this,
                callfuncND_selector(RequestHandler::requestCallback),
                (void*)pRequestData));