This problem has been haunting me for a week now, so I had to ask.
I wanted to do an overlay layer, something like a pop up menu in one of my scenes. I added a ColoredLayer member to my scene class. I initialize the layer in the scene’s init() function. But I never added it to the scene as a child. Then when I try to add it (triggered by some logic in the game), it assert-fails saying “Assert failed: child already added. It can’t be added again”.
I have checked everywhere in my code, seriously I never added the layer to the scene. And I have debug-print its parent pointer. In the scene’s init() function (where I create the layer), it was still 0x0 (nullptr), but then the next print I have (a few seconds later, or from some in-game logic) will show that the parent pointer is set to some meaningful value.
Q1: How can this happen?
Q2: I’m running out of thoughts on how to debug this. What should I check for?
Thank you in advance for your time and thoughts!!
Hello @royitaqi !
I’m not sure I understood you correctly.
If you create a layer in the init() function, but did not add it as a child to any node, then the layer will be deleted at the end of the init(), and you can not use it.
If you create a layer in the init() function, and add it as a child to any node, then you must first remove the layer from its parent, and then add it to your scene. Because any node (including layer) can not have two parents simultaneously.
I created the layer in init() but then hold the pointer as the scene class’s member without adding it to the scene graph.
Hope this makes things clearer.
You should show your code.
If you do not use the addChild(layer) or retain(layer), then the layer object will be deleted at the end of the init function, and your pointer will be now refers to an unknown.
That is why you have the fake parent after a while.
p.s. My suggestion is do not create this layer in the scenes init function, create it when you need it and add immediately as a child to the scene.
Ah! Seems like a reasonable explanation. How do I test if the layer object is still valid?
Now I thought about it, besides your suggestion, I can also create and add the layer to the scene but mark it invisible to achieve the same effect of holding the layer but not using it yet. Is there any difference between these two approaches?
@royitaqi
Sorry for the late reply.
If the scene has it as a child, then it is valid. It is also possible to use retain(), but I never used it, so I can not say more.
I think that your last approach is the best solution.