Generating Linear Hierarchy from a Typelist

258 Views Asked by At

I'm going through "Modern C++ Design" and I've run into an issue with the GenLinearHierarchy explained at the end of chapter 3.

Since there's no code provided on how to call functions and deal with the generated hierarchy in general, I can't tell if what I've written is correct or not. The book simplifies the use of this technique a lot so it's hard to tell.

I looked through the AbstractFactory example in the Loki library and just changed it to work with what I wanted, but I have a feeling that I'm taking an extra step somewhere.

The GenScatterHierarchy and GenLinearHierarchy are the same as defined here

My code:

template<class T>
class AbstractCollisionEvent
{
public:
    virtual void Collision(int id, T& obj) = 0;
    virtual ~AbstractCollisionEvent() {};
};


template <class T, class Base>
class CollisionEventImpl : public Base
{
    typedef typename Base::ProductList BaseProductList;

protected:
    typedef typename BaseProductList::Tail ProductList;

public:
    typedef typename BaseProductList::Head AbstractProduct;
    void Collision(int id, AbstractProduct& obj)
    {
        obj.Collided(id, Chapter2::Type2Type<AbstractProduct>());
    }
};

template
<
    class TList,
    template <class> class Unit = AbstractCollisionEvent
>
class CollisionHandlerScatter : public HierarchyGenerators::GenScatterHierarchy<TList, Unit>
{
public:
    typedef TList ProductList;

    template<class O>
    void OnCollide(O& obj, int id)
    {
        Unit<O>& unit = *this;
        unit.Collided(id, obj);
    }
    virtual ~CollisionHandlerScatter() {}
};

template
<
    class AbstractHandler,
    template <class, class> class Handler,
    class TList
>
class ConcreteCollisionHandler : public  HierarchyGenerators::GenLinearHierarchy<TList, Handler, AbstractHandler>
{

};

class Explode
{
public:
    void Collided(int id, Chapter2::Type2Type<Explode>)
    {
        std::cout << "Exploded!";
    }
};

class Spawn
{
public:
    void Collided(int id, Chapter2::Type2Type<Spawn>)
    {
        std::cout << "Spawned!";
    }
};

class Heal
{
public:
    void Collided(int id, Chapter2::Type2Type<Heal>)
    {
        std::cout << "Heal!";
    }
};

typedef TYPELIST_3(Spawn, Explode, Heal) colliderTL;
typedef CollisionHandlerScatter<colliderTL> CHS;
typedef ConcreteCollisionHandler<CHS, CollisionEventImpl, colliderTL> CCH;


CCH cch;
Spawn s;
Heal h;
cch.OnCollide(s, 1);
cch.OnCollide(h, 1);

This code works. But I feel like "AbstractCollisionEvent" and "CollisionEventImpl" are just useless layer, or at least that's how it looks with the way the books explains it. I haven't been able to implement the behavior I want without those two and I was wondering if there is one or if there is a way to improve what I have.

0

There are 0 best solutions below