0

I have written a messaging system which relies a lot on compile-time mechanics. To receive messages, you inherit from a class template like so:

class WorldRenderer : public fea::MessageReceiver<SpriteCreateMessage>,
                      public fea::MessageReceiver<SpritePositionMessage>,
                      public fea::MessageReceiver<SpriteMoveMessage>
{
public:
    void handleMessage(const SpriteCreateMessage& mess) override;
    void handleMessage(const SpritePositionMessage& mess) override;
    void handleMessage(const SpriteMoveMessage& mess) override;
};

I was thinking it there was a way to shorthand this notation in a neat way using macros. How I imagine said macro to be used:

class WorldRenderer
FEA_IS_RECEIVER(SpriteCreateMessage, SpritePositionMessage, SpriteMoveMessage)
{
public:
    void handleMessage(const SpriteCreateMessage& mess) override;
    void handleMessage(const SpritePositionMessage& mess) override;
    void handleMessage(const SpriteMoveMessage& mess) override;
};

Is there a way to create such a FEA_IS_RECEIVER macro?

I have looked into variadic macros but it doesn't seem possible to evaluate them unless you write specific macro overloads for every specific amount of parameters. This approach would work but would limit the amount of messages you can subscribe to.

Is there at all a neat way to achieve what I am trying to do?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Tobias
  • 924
  • 9
  • 23

2 Answers2

2

How about adding an intermediate set of classes:

template <typename T>
struct MiddleRenderer : T
{
    void handleMessage(const SpriteCreateMessage& mess) override
    {
        // ...
    }
};

template <typename ...Args>
class WorldRenderer : public MiddleRenderer<Args>...
{
    // ...
};

Now you can use WorldRenderer<SpriteCreateMessage, SpriteMoveMessage> etc. and get a class that is derived from all the listed classes.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • This would be a possible end user solution, but my message system is part of a library that doesn't know which message types will be defined by the user, and I was looking for a macro to include in the library. But thanks anyway – Tobias Jan 30 '14 at 06:27
  • @Tobias: Have a look at Boost.Preprocessor, which has some fairly advanced stuff. – Kerrek SB Jan 30 '14 at 06:29
1

I don't think the syntax you're looking for is going to work. Maybe something like this would be equally usable:

class WorldRenderer :
  FEA_IS_RECEIVER(SpriteCreateMessage),
  FEA_IS_RECEIVER(SpritePositionMessage),
  FEA_IS_RECEIVER(SpriteMoveMessage)
{
public:
    void handleMessage(const SpriteCreateMessage& mess) override;
    void handleMessage(const SpritePositionMessage& mess) override;
    void handleMessage(const SpriteMoveMessage& mess) override;
};
ioctl
  • 136
  • 4
  • Yeah, that would work. But IMO that is almost as verbose as the original case without a macro so there wouldn't be that much point. :) – Tobias Jan 30 '14 at 06:28