I am writing my own small game engine (thin layer based on SDL2) in C++. My base class is Node (contains information on an entity's position, scale, rotation, etc.), And I've got two special subclasses, Layer and Scene.
Node
|_SpriteNode
|_RectNode
|_...
|_Layer
|_Scene
A layer can have Node
children. Each time the loop runs, I call the update(int timeInterval)
method on the scene being rendered, and the method loops through the vector<Node*>
field containing my children. Layers propagate that call to their children, etc.
This works well until I start adding/removing children during the update. My first implementation of Layer
had those two methods:
void Layer::addChild(Node* child)
{
if(!child) return;
_children.push_back(child);
}
void Layer::removeChild(Node* child)
{
_children.erase(child)
}
This is, of course, stupid, since removing a Node from the vector would cause a null pointer error when the update loop ( for (auto child: _chidren)
). Using an iterator instead could fix this, but when a Node calls _parent.removeChild(this)
, it does not know about the iterator being used for that frame.
The solution I use at the moment is having an addition and a deletion buffer in the Layer, to which new and deleted nodes are added during the frame update. Once the frame has been rendered, the Layer performs the actual insertions and deletions from its children array. It works, and I've made a Game Jam game with this, but is seems more than sketchy to me.
I have looked through Cocos2D-X source code, and they use a simple push_back()
or erase()
call, which makes me think I'm missing a bigger point, or some trick that prevents the iterator issue. Is there something obvious (or not) that I missed?
Sorry if the question is dumb or missing a point. I hope I documented everything enough :)