Saturday, August 19, 2017

Organizing classes 3/3

Modularized class


In previous post, I show the design of composite class.
It looks almost nice but it' a bother to write/use accessor functions to each component.

The third idea here I introduce is something I call 'modularized class'.

class Object
{
public:
    virtual ~Object() {} // make Object polymorphic.
};

// component classes deriving Object 'virtual'ly.
class Input : public virtual Object
{
    ...
};
class AIParam : public virtual Object
{
    ...
};
class Position : public virtual Object
{
    ...
};
class Health : public virtual Object
{
    int health;
public:
    void apply_damage(int damage) {

        // when this object inherits TimeStatus, calcurate damage by the status
        TimeStatus* s = dynamic_cast<TimeStatus*>(this);
        if( s ) {
            // do some culcuration.
        }
        health -= damage;
    };
};
class TimeStatus : public virtual Object
{
    ...
};

template <typename... Modules>
class ModularObject : public Modules...
{
};

// Player, Enemy, Obstacle class inherits each component class.
// template class ModularObject is used for utility.
typedef ModularObject<Input, Position, TimeStatus, Health> Player;
typedef ModularObject<AIParam, Position, TimeStatus, Health> Enemy;
typedef ModularObject<Position,Health> Obstacle;

// use like this. (using template)
template <typename T>
void attack(int damage, T* obj)
{
    // when obj does not inherit Health, this gets compile error.
    obj->apply_damage(damage);
}

// or use dynamic_cast
void attack(int damage, Object* obj)
{
    // when obj does not inherit Health, nothing happens.
    Health* h = dynamic_cast<Health*>(obj);
    if( h ) {
        h->apply_damage(damage);
    }
}

This approach uses multiple inheritance. and virtual inheritance which solves 'diamond problem'.

It's easy to add/remove features, and can access components directory.

I think this is the best solution for organizing class for game object.



No comments:

Post a Comment

It&#39;s magic! std::bind

'std::bind' is a powerful helper for working around 'std::function'. 'std::bind' makes a instance of 'std::fun...