tl;dr

February 17, 2010

Flat hierarchies in C++: Part 1

Filed under: Concurrent Programming,Software — dublindan @ 10:58 pm
Tags:

I have decided that the time has come to finish the mini series on flat hierarchies in C++. This part, Part 1 of the new and improved series, is simply a reiteration of my earlier post on the subject, with a full, compilable, code listing. For an explanation, please read the other post. The next part of the series will decouple the components in preparation of adding concurrency.

#include <map>
#include <vector>
#include <iostream>
#include <cstdlib>

class Event {
public:
    Event (unsigned int t) : type(t) {}
    virtual ~Event () {}

    const unsigned int type;
};

class Component {
private:
     static std::map > eventMap;
protected:
     // Register for all events of type "type".
     void registerForEvent (const unsigned type);
     // Send an event.
     void send (const Event* const event);

public:
     // Event handler, called when an event, which is being listened for, is received.
     virtual void eventReceived(const Event* const event)=0;
};

std::map<unsigned int, std::vector<Component*> > Component::eventMap;

void Component::registerForEvent (const unsigned int type) {
    eventMap[type].push_back(this);
}
void Component::send (const Event* const event) {
    std::vector& components = eventMap[event->type];
    for (std::vector::iterator i = components.begin(); i != components.end(); i++) {
        (*i)->eventReceived(event);
    }
}

enum EventIdentifiers {
    QUIT_EVENT=0,
    PRINT_HELLO,
    PRINT_MESSAGE
};

class MessageEvent : public Event {
public:
    MessageEvent () : Event(PRINT_MESSAGE) {}
    virtual ~MessageEvent () {}

    std::string message;
};

class HelloPrinter : public Component {
public:
    HelloPrinter () {
        registerForEvent(QUIT_EVENT);
        registerForEvent(PRINT_HELLO);
        registerForEvent(PRINT_MESSAGE);
    }
    virtual ~HelloPrinter () {}

    void eventReceived(const Event* const event) {
        if (event->type == QUIT_EVENT) {
            std::exit(0);
        }
        else if (event->type == PRINT_HELLO) {
            std::cout << "Hello!\n";
        }
        else if (event->type == PRINT_MESSAGE) {
            std::cout << "Message: " << static_cast<const MessageEvent*>(event)->message << "\n";
        }
    }

    void sendQuit () {
        Event event(QUIT_EVENT);
        send(&event);
    }
    void sendHello () {
        Event event(PRINT_HELLO);
        send(&event);
    }
     void sendHelloMessage (const std::string& message) {
        MessageEvent event;
        event.message = message;
        send(&event);
    }
};

int main (int argc, char** argv) {
    HelloPrinter a, b, c;
    a.sendHello();
    b.sendHelloMessage("Hi from b");
    c.sendQuit();
}

Advertisement

Leave a Comment »

No comments yet.

RSS feed for comments on this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.