2013-11-01

Make message interaction more readable, by using c++ local class





main (1).cpp



Make message interaction more readable, by using c++ local class::::

c++ local class:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr062.htm


/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <map>

using namespace std;

#define MESSAGE_SEND       3
#define MESSAGE_TIME_OUT   4
#define MESSAGE_RESPONSE   5

/////////////////////////////////////////////////////////////////////////////
struct Worker {
    virtual void operator()() = 0;
};

/////////////////////////////////////////////////////////////////////////////
struct HandlerPool {
    void addMsg(int msg, Worker& a) {
        maps[msg] = &a;
    }

    void run(int msg) {
        if (maps.find(msg) != maps.end()) {
            (*maps[msg])();
        } else {
            cout << "no handler" << endl;
        }
    }

    map<int, Worker*> maps;
};

HandlerPool g_handlePool;
/////////////////////////////////////////////////////////////////////////////
#define if_on_msg(msg) IF_ON_MSG(onMsg_##msg)

#define IF_ON_MSG(msg_handler_class)        \
static struct msg_handler_class : Worker {  \
    void operator()()

#define end_if_on_msg(msg) END_IF_ON_MSG(msg, onMsg_##msg##_handler)

#define END_IF_ON_MSG(msg, handler_instance_name) \
} handler_instance_name;                          \
g_handlePool.addMsg(msg, handler_instance_name)

/////////////////////////////////////////////////////////////////////////////
struct Worker_Before_refactor : Worker {
    void processMsg(/*const Message& msg*/) {

        //`people can not see which message came first, which is the last one`
        //`so can not know the message_interaction by reading code`

        switch (msg) {
            case MESSAGE_TIME_OUT: 
              ....
            case MESSAGE_RESPONSE: 
              .... 
            case MESSAGE_XXXX: 
              ....
            case MESSAGE_YYYY: 
              ....
        }
    }
};

/////////////////////////////////////////////////////////////////////////////
struct WorkerAfterRefactor : Worker {
    void operator()() {
        sender------->receiver(MessageBody);

        if_on_msg(sender<------------receiver(MESSAGE_TIME_OUT)) {

            sender------->receiver(MessageBody);
            if_on_msg(sender<------------receiver(MESSAGE_TIME_OUT)) {
                cout << "retry still got timeout..." << endl;
            } end_if_on_msg(MESSAGE_TIME_OUT);

        } end_if_on_msg(MESSAGE_TIME_OUT);

        if_on_msg(sender<-----receiver(MESSAGE_RESPONSE)) {
            cout << "succeeded got ack" << endl;
        } end_if_on_msg(MESSAGE_RESPONSE);
    }
};

/////////////////////////////////////////////////////////////////////////////
int main(int argc, const char * argv[])
{
    WorkerAfterRefactor a;

    g_handlePool.addMsg(MESSAGE_SEND, a);

    g_handlePool.run(MESSAGE_SEND);
    g_handlePool.run(MESSAGE_TIME_OUT);
    g_handlePool.run(MESSAGE_TIME_OUT);
    g_handlePool.run(MESSAGE_RESPONSE);

    return 0;
}
/////////////////////////////////////////////////////////////////////////////
//output:
//------>send sca config to slave board
//<----timeout...
//----->retry send sca config to slave board
//<-----retry still got timeout...
//<----succeeded got ack
//
//Process finished with exit code 0