How should an object that uses composition set its composed components?

Posted by Casey on Game Development See other posts from Game Development or by Casey
Published on 2014-05-27T20:15:17Z Indexed on 2014/05/28 10:09 UTC
Read the original article Hit count: 341

Filed under:
|

After struggling with various problems and reading up on component-based systems and reading Bob Nystrom's excellent book "Game Programming Patterns" and in particular the chapter on Components

I determined that this is a horrible idea:

//Class intended to be inherited by all objects. Engine uses Objects exclusively.
class Object : public IUpdatable, public IDrawable {
public:
    Object();
    Object(const Object& other);
    Object& operator=(const Object& rhs);

    virtual ~Object() =0;

    virtual void SetBody(const RigidBodyDef& body);
    virtual const RigidBody* GetBody() const;
    virtual RigidBody* GetBody();

    //Inherited from IUpdatable
    virtual void Update(double deltaTime);

    //Inherited from IDrawable
    virtual void Draw(BITMAP* dest);


protected:
private:
};

I'm attempting to refactor it into a more manageable system. Mr. Nystrom uses the constructor to set the individual components; CHANGING these components at run-time is impossible. It's intended to be derived and be used in derivative classes or factory methods where their constructors do not change at run-time. i.e. his Bjorne object is just a call to a factory method with a specific call to the GameObject constructor.

Is this a good idea? Should the object have a default constructor and setters to facilitate run-time changes or no default constructor without setters and instead use a factory method?

Given:

class Object {
public:
    //...See below for constructor implementation concerns.
    Object(const Object& other);
    Object& operator=(const Object& rhs);

    virtual ~Object() =0;

    //See below for Setter concerns
    IUpdatable* GetUpdater();
    IDrawable* GetRenderer();

protected:
    IUpdatable* _updater;
    IDrawable* _renderer;
private:
};

Should the components be read-only and passed in to the constructor via:

class Object {
public:
    //No default constructor.
    Object(IUpdatable* updater, IDrawable* renderer);
//...remainder is same as above...
};

or Should a default constructor be provided and then the components can be set at run-time?

class Object {
public:
    Object();
//...
SetUpdater(IUpdater* updater);
SetRenderer(IDrawable* renderer);
//...remainder is same as above...
};

or both?

class Object {
public:
    Object();
    Object(IUpdater* updater, IDrawable* renderer);
//...
SetUpdater(IUpdater* updater);
SetRenderer(IDrawable* renderer);
//...remainder is same as above...
};

© Game Development or respective owner

Related posts about c++

Related posts about component-based