Friday, 16 March 2012

17

12 March - 16 March 2012
Found some Intercom coding make reference.

Message

template <class ST, class CT>


struct Message
{
public:
typedef ST SubjectType;
typedef CT CodeType;


Message() : subject(), code() {}
Message(SubjectType s, CodeType c) : subject(s), code(c) {}


SubjectType subject;
CodeType code;
};


The message template provides the type on which Observer and Notifier are paramaterized.  Different instantiations of Message will lead to different instantiations of Observer and Notifier (and MessageMap andMessageSource, for that matter), so it's important to understand it well.  The good news is that there isn't much to Message -- just two typedefs, two data members and a two constructors.  The typedefs serve to "publish"Message's parameters to other code.  Inside Observer and Notifier those typedefs are used to instantiate code (for example, MessageMap has a member that is a map of Message<>::CodeType to PMethod function pointers).  You can easily create a substitute for Message so long as it adheres to the basic "interface" shown here.
Objects of Message types are fairly lightweight, containing just two data members only one of which is likely to be a pointer.  Still, we don't want to make a lot of copies of them, or repeatedly construct and destruct them.  I stopped short of adding a private copy constructor and assignment operator, for flexibility, but they might be well advised if your code or user data types are large or complex.
The following line declares a Message instantiation with a code type of int and a subject type of const Foo*:
typedef Mm::Message<const Foo*, int> MyMessage;
In this example, I chose a const subject type to illustrate the need for the non-default constructor.  There are situations where aspects (code, subject or user data) of a message type should always be considered non-volitile.  It is possible in those cases to make the subject and or code types const, and hence protect them from modification outside initialization.  However, since a const public member cannot be assigned outside of the initializer, a non-default constructor is required.  Specializing Message is possible and probably the best way to add user-defined data to messages.  For example:

typedef Mm::Message<const Foo*, int> MyMessage;
struct PingMessage : public MyMessage
{
PingMessage() : MyMessage() {}
PingMessage(MyMessage::SubjectType s, MyMessage::CodeType c)


std::list<Bar*> responders;
}


This example declares a message class that included a list of responders.  Assuming that any Bar handling the message adds itself to the list, this type of construct can be useful as a 'ping' -- that is, to see who's listening to a particular Foo.  Of course, adding a reference to Bar in the message definition creates a link (albiet a weak one) between the classes that may not be desirable.  Using an orthogonal SubjectType would eliminate the link.


Observer

template <class M> struct Observer { public: typedef M MessageType; virtual Result OnMessage(const MessageType& message) { return Result(R_OK); } virtual Result Goodbye(const MessageType::SubjectType s) { return Result(R_OK); } };
Observer defines the interface of the client.  That is, messages are passed to and handled by objects implementing the Observer interface appropriate to the message type.  Observer is templatized on the message type, so each type of message will have an insulated, non-overlapping interface.  It is expected that users of Intercom will create implementations of this interface, or use the concrete MessageMap described below.
The interface consists of two methods:
  • The method OnMessage() is called each time a message dispatched on behalf of a subject to which the observer is registered.  The observer receives a const reference to a message of the type used to instantiate the template (MessageType), and is generally expected to return some status though it goes unused in Intercom at the moment.
  • The method Goodbye() is not described by Gamma, though is often found in practice.  This method is called when the registration of the observer is revoked from a particular subject and will no longer get notifications.  The method provides the observer with a convenient opportunity to do finalization or cleanup without having to define a protocol specific to the purpose.



Reference from here