I have a base class
Object, and depending on how the object must behave on the scene, I have multiple abstract "role" classes, that inherits virtually from
Updatableif the object is dynamic, and must be updated every frame;
Collidableif the object can collide with others, and thus must take part on collision detection;
Drawableif the object is visible and must be drawn.
So, for instance, a particle special effect animation is both a
Updatable, because it moves, and
Drawable, because it is visible, but is not
Collidable. A trigger may be
Updatable, but is definitely
Collidable, and is not
Drawable because it is invisible.
If objects are never removed or created, this design is easy to manage: I have three lists on my world, one for each object type, that hold pointers for all objects of that type: i.e. the
updatable_list holds a pointer to all my
Updatables, etc. This is what I have so far.
Now I have to add and remove objects, and this design is biting me.
When a new object is added, I would have to use
dynamic_cast to figure out its roles and add its pointer to the proper lists. But
dynamic_cast is usually referred as bad design and code smell, not to mention being slow.
When an object is removed, it can potentially be part of multiple lists, so I would have to track its existence across lists, maybe by storing
std::weak_ptr instead of raw pointers, and would have to check and potentially remove every time I use an object from such list. Other options would be linear search and remove from all lists upon removal, or use
std::unordered_set instead of
std::list to make it fast to search and remove. But I find these other options a bit fragile, because I risk having dangling pointers if I "forget" to remove the object from some list.
So, my question, is this a good design? How can it be improved? How is this problem of different object types usually handled in game engines?