Is there a way to copy CCMenuItem... objects? may be this is a bug.

Hello.
I try create copy of CCMenuItem, CCMenuItemImage, CCMenuItemSprite and etc… All of this classes produce an crash if I try add their to CCMenu.

My code looked like this:

CCMenuItemImage* close_item = CCMenuItemImage::itemFromNormalImage(
      "CloseNormal.png",
      "CloseSelected.png",
      this,
      menu_selector(MenuScene::menuCloseCallback));
close_item->setPosition(CCPointZero);
CCMenuItemImage* copy_item(close_item);
CCMenu* menu_1 = CCMenu::menuWithItems(close_item, copy_item, NULL);

crashed at - CCAssert( child~~>m_pParent == NULL, “child already added. It can’t be added again”);
I looked classes CCMenuItem, CCMenuItemImage, CCMenuItemSprite…
and found that all classes don’t have copy constructor~~ declaration, definition or
explicit prohibition copying (something like this:

class T { 
private:
    Т( const T& );  // without definition
    Т& operator=( const T& );  // without definition
}; 

)

This look like a bug. Maybe i’m wrong? Maybe correct way to copy MenuItems objects exist?

Sorry, the copy method has not been implemented so far.
You had to create the item twice here.

Quick question, can you not reference instance members in the callback function of another class?

void OtherClass::init()
{
CCMenuItemImage* close_item = CCMenuItemImage::itemFromNormalImage(
“normal.png”, “selected.png”,this, menu_selector(MenuScene::menuCloseCallback));
}


void MenuScene::menuCloseCallback(CCObject* sender)
{
member~~>DoStuff;
}
It makes sense, since the callback is referring to class method instead of the method of an instance. But is there any way to reference the object’s member? I tried wrapping with another class function:
void MenuScene::DoStuff
{
member~~>DoStuff();
}

void MenuScene::menuCloseCallback(CCObject* sender)
{
DoStuff();
}

It doesn’t work because when I break at the code the member pointer has corrupt data. It seems that the only solution would be to use a static member.

Sorry, I don’t know what you want to do.

I setup a callback to: MenuScene::menuCloseCallback

it’s referring to a class method, not an object method.

It’s fine, I just have to reimplement MenuScene as a singleton and maybe do something like this:
void MenuScene::menuCloseCallback(CCObject* sender)
{
sharedInstance()>member>DoStuff();
}

I don’t know if I catch your idea.
Callback of MenuScene::menuCloseCallback is not a class method. You can refer HelloWorld, menuCloseCallback is not a class method.

Okay, well I setup the callback from a different class (not HelloWorld).

void OtherClass::init()
{
CCMenuItemImage* close_item = CCMenuItemImage::itemFromNormalImage(
“CloseNormal.png”,
“CloseSelected.png”,
this,
menu_selector(MenuScene::menuCloseCallback));
}

How does it know which “MenuScene::menuCloseCallback” to call? For example, say I had two instances (not that I would). So if I had two instances, would I get two calls to MenuScene::menuCloseCallback? One for each instance?

If I break inside of MenuScene::menuCloseCallback and take a look at ‘member’, which is a pointer to a derived class of CCSprite, it’s a bad pointer.

It can not used in this way. As fact, only the classes that inherit from SelectorProtocol can use it. And it points the object that use the menu_selector.

Just to verify, this is not possible?

class Menu: public cocos2d::CCLayer
{
public:

CCSprite* sprite;

void aCallback(cocos2d::CCObject* sender)
{
sprite->Something();
}
};

class OtherClass: public cocos2d::CCLayer
{
public:

void init() {
CCMenuItemImage* close_item = CCMenuItemImage::itemFromNormalImage(“n.png”,“s.png”,this,menu_selector(Menu::aCallback));

}
};

Yeap. It is impossible.

Okay, well if anyone has a similar problem in the future, this is what I did.

class UI: public cocos2d::CCLayer
{
public:
//…
bool init()
{
CCMenuItemImage* item = CCMenuItemImage::itemFromNormalImage( … , menu_selector(UI::callback));
//…
}

void callback(cocos2d::CCObject* sender)
{
MainLayer* ml = (MainLayer*)getParent();
ml->FunctionToCall();
}
};

If at the now many classes don’t have copy constructors

  • May be it’s good idea to explicitly disallow copying ( for detect copying errors at compile time.)?
    Like in my sample above.

I think that’s a good idea for the next patch.

#699 is created for it.