c++cocos2d-xcocosbuilder

How to access variables in a sub-ccb file with a custom class as root node in cocos2d-x


Let's say I have two ccb files

FriendList.ccb associate with a class named FriendList, it will read nodes from this ccb file with the code like below:

CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::sharedCCNodeLoaderLibrary();
CCBReader reader = CCBReader(ccNodeLoaderLibrary);
CCLayer* layer = (CCLayer*)reader.readNodeGraphFromFile("FriendList.ccbi", this);

Friend.ccb associate with a custom class name Friend and a custom loader named FriendLoader. It can also contain its own variables, such as CCLabelTTF, CCSprit.

And in FriendList.ccb, it can contains many Friend.ccb as sub ccb file.

After these define, I now assume there are two Friend.ccb in FriendList.ccb, named m_friend1 and m_friend2, and in Friend.ccb there is a CCLabelTTF name m_friend_name.

I load the two instance of Friend with the following code in FriendList.cpp:

bool FriendList::onAssignCCBMemberVariable(CCObject *pTarget, CCString *pMemberVariableName, CCNode *pNode){
    CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "m_friend1", Friend*, m_friend1);
    CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "m_friend2", Friend*, m_friend2);
    return false;
}

and load the instance of the CCLabelTTF with the following code in Friend.cpp:

bool Friend::onAssignCCBMemberVariable(CCObject *pTarget, CCString *pMemberVariableName, CCNode *pNode){
    CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "m_friend_name", CCLabelTTF*, m_friend_name);
    return false;
}

With these work, I can access m_friend1 and m_friend2 successfully, but when accessing m_friend1->m_friend_name, I got EXC_BAD_ACCESS.

So how can I access the variables in sub ccb file?


Solution

  • When using a sub ccb file associate with a custom clase, we need add a custom loader first.

    Let's name it FriendLoader, there is the code in FriendLoader.h:

    #include "Friend.h"
    
    /* Forward declaration. */
    class CCBReader;
    class FriendLoader : public cocos2d::extension::CCLayerLoader {
    public:
        CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(FriendLoader, loader);
    
    protected:
        CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(Friend);
    };
    

    And register it in AppDelegate::applicationDidFinishLaunching():

    CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::sharedCCNodeLoaderLibrary();
    ccNodeLoaderLibrary->registerCCNodeLoader("Friend", FriendLoader::loader());
    

    or some other place you like.

    Then we can use the custom class(Friend) in ccb file. Open Friend.ccb file, select the root node, and fill in the 'Custom class' blank with Friend.

    Then select the CCLabelTTF named m_friend_name, and select the 'Doc root var', this is very important ! ! !.

    Here I want give a simple explain.

    Since in FriendList class, it reads node from ccb file with reader.readNodeGraphFromFile("FriendList.ccbi", this);, and using itself as a 'owner', so these variables in it are 'owner var'. When reading nodes, the CCBReader will assign these 'owner var' to this 'owner' that is a FriendList instance directly.

    While Friend is a custom class used in CocosBuilder, it is the root node in Friend.ccb, and the variable in it is 'Doc root var'. When reading nodes, the CCBReader will first read the instances of Friend, then assign these 'Doc root var' to these instances.

    So what make me failed before is indeed these, I select 'owner var' of all of the variables in both FriendList.ccb and Friend.ccb.

    Then CCBReader assign the variable m_friend_name in sub Friend.ccb to the 'owner'( an instance of Friend).

    For more information, can see CocosBuilder: Connecting with cocos2d-x.