Struan wrote:
I think it is just the decorator pattern.
It's not really the decorator pattern. It's even more basic than that. It's just an appropriate use of an OO feature, i.e. composition. You can compose one class out of many other classes, all it takes is that it's declared as a member variable. You do this all the time in OO. The only way to bring in functionality from another class is by inheritance or composition. Inheritance implies heirarchy though, which is sometimes a hinderance.
The idea here is that it's better to use composition than inheritance in a game engine because of the problem of designing a heirarchy that has no overlaps. The idea is extended by creating a generic way to add components to a game object, which is by making all components inherit from a base component class. This is all still just the very basic OO thing of composition. A game object has a list of components as a member variable. By adding components, the game object gains functionality.
The decorator pattern works in the opposite direction and uses inheritance. You have a base class Drawable and some object X. You want to add functionality Y to X. You create a class Y which inherits from Drawable and will contain a Drawable component. Now to decorate X with Y you create a Y object and place X inside it. When you call y.draw() then Y will call x.draw() and afterwards do whatever decorations it wants to do on top of that. So the idea is then that code that used to operate on X can now operate on Y in exactly the same way, as if it were just an X - but you get the extra Y functionality. This way, you end up with a chain or linked list, which is not going to be efficient.
In terms of implementation you have your GameObject with a list of Components. Each update of the GameObject will call each Component's update function. GameObject should also have a function along the lines of bool hasComponent(string c) so that other objects can check its functionality. You would probably want components to have access to their owners, so update should maybe be along the lines of void update(GameObject* g).