Exercise+8

=Exercise 1.1: Class MessageHandler= toc MessageHandler er basis klassen, som styrer alle de tråde der vil modtage en besked.

Interface:

Klassens metoder skal indeholde følgende:

MessageHandler(ThreadPriority pri, string name) Constructor. Sets the priority and name of this MessageHandler. code format="cpp" MessageHandler::MessageHandler(ThreadPriority pri, string name) : Thread( pri, name) {   mailbox = new Mailbox(10); } code

~MessageHandler Destructor. Detaches from all messages registered by this MessageHandler. code format="cpp" MessageHandler::~MessageHandler {   for (unsigned int i = 0; i < attachedMsgs.size; i++) Message::detach(attachedMsgs[i], mailbox); delete mailbox; } code

run Thread function. Forever receives messages in mailbox, casts them to Message objects and forwards them to handleMessage

code format="cpp" void MessageHandler::run {   MarshalledMessage mObj; Message* messagePtr;

while(true) {       mObj = mailbox->get; messagePtr = reinterpret_cast(&mObj); handleMessage(messagePtr); } } code

attachTo(MessageType t) Attaches this MessageHandler to message type t (see Message::attach) and adds t to attachedMsgs (the list of messages to which this MessageHandler is attached). code format="cpp" void MessageHandler::attachTo(MessageType t) { attachedMsgs.push_back(t); Message::attach(t, mailbox);

} code

handleMessage(Message* msg) Pure virtual method: Gets called each time a message is received for this MessageHandler. Must be implemented by the concrete, inheriting MessageHandler which should switch on msg->getType and downcast msg to the specific type before handling it.

Ingen kode da denne er virtuel.

=Exercise 1.2: Class Message=

Klassen Message skal laves ud fra følgende interface:

og metoderne skal indeholde følgende:

Message(MessageType t) Constructor. Sets the type of this message to t code format="cpp" Message::Message(MessageType t) { type = t; } code

attach(MessageType t, Mailbox* mb) Static method. Adds mb to the list of mailboxes for message type t code format="cpp" void Message::attach(MessageType t, Mailbox * mb) {   if(find(observers[t].begin, observers[t].end, mb) == observers[t].end) observers[t].push_back(mb); } code

detach(MessageType t, Mailbox* mb) Static method. Removes mb to the list of mailboxes for message type t mb to the list of mailboxes for message type t code format="cpp" void Message::detach(MessageType t, Mailbox * mb) {   remove(observers[t].begin, observers[t].end, mb); } code

send Copy the data contents of the message (this) into a MarshalledMessage object and put a copy of it into each of the MessageHandler's for the type of this message code format="cpp" void Message::send {   MarshalledMessage mMsg; ObserverList::iterator i;

memcpy(&mMsg, this, getSize);

i = observers[type].begin; for(i != observers[type].end ; ++i) {       (*i)->put(mMsg); } } code

getType Return the type of this message code format="cpp" MessageType Message::getType {   return type; } code

getSize Pure virtual method. Must be implemented by all subclasses. Returns sizeof(*this) The class should also contain an STL map observers. This should map message types to a list of mailboxes, so that send can easily find and notify all observers of a specific message.

Ingen cpp kode da denne metode er virtuel.

=Exercise 1.3:=

I en separat headerfil "MsgDefs.h" laves en struct og en enum. code format="cpp" enum MessageType {       // Her defineres hvilke besked-typer der findes SPEED_MSG, HEADING_MSG };

struct MarshalledMessage {       // Besked-holder char data[50]; }; code

=Exercise 2.1 Define new messages:=

Der skal oprettes to klasser "SpeedMessage" og "HeadingMessage", disse skal begge arve fra "Message", og laves ud fra følgende diagram.

Konstruktoren skal sætte "SpeedMessage" og "HeadingMessage" type til henholdsvis SPEED_MSG og HEADING_MSG.

for speedMessage, setSpeed kan evt sætte til 0: code format="cpp" SpeedMessage::SpeedMessage : Message(SPEED_MSG) {   //setSpeed(0); } code

=Exercise 2.2 Define message recipients:=

Opret en klassen ved navn "SpeedHandler" som arver fra MessageHandler:

Udfra den udleveret pseudo kode, skal "handleMessage" laves: code format="cpp" void SpeedHandler::handleMessage(Message* msg) {   SpeedMessage* speedMsg; switch(msg->getType) {   case SPEED_MSG: speedMsg = static_cast(msg); cout << "Got speed message with speed " << speedMsg->getSpeed << endl; break; default: break; } } code

SpeedHandler's konstrukter skal implementeres således at ved oprettelse af et SpeedHandler objekt opretter forbindelse til SpeedMessages code format="cpp" SpeedHandler::SpeedHandler(ThreadPriority pri, string name) : MessageHandler(pri, name) {   MessageHandler::attachTo(SPEED_MSG); } code

Ligesom overfor skal dette gøres for "HeadingHandler" code format="cpp" HeadingHandler::HeadingHandler(ThreadPriority pri, string name) : MessageHandler(pri, name) {   MessageHandler::attachTo(HEADING_MSG); }

void HeadingHandler::handleMessage(Message* msg) {   HeadingMessage* headingMsg;

switch(msg->getType) {   case HEADING_MSG: //headingMsg = reinterpret_cast(msg); headingMsg = static_cast(msg); cout << "Got heading message with heading " << headingMsg->getHeading << endl; break; default: break; } } code

=Exercise 3.1:=

Test programmet skal oprette to tråde (SpeedHandler og HeadingHandler). Derefter skal mainen udskrive hvilken type besked brugeren vil sende og hvilken værdi der skal sendes, og tilsidst sende den afsted. Ved korret anvendelse af programmet skal brugen nu modtage en udskrift om hvilken besked der er sendt og hvilken værdi der er sendt.

=Exercise 4.1: Define a new receiver=

Når der skal oprettes en ny modtager, skal man oprette en klasse som arver fra"MessageHandler", denne nye klasse skal laves ligesom "SpeedHandler" og "HeadingHandler" dvs i constructoren skal den attachesTo den/de meddelslse(r) den ønsker at abonnere. Mens handelMessage skal initieres, så den håndterer beskeden/beskederne på den ønskede måde. I main skal der tilsidst oprettes en ny tråd.