Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

NotificationBoard Class Reference

#include <NotificationBoard.h>

List of all members.


Detailed Description

Acts as a intermediary between module where state changes can occur and modules which are interested in learning about those changes; "Notification Broker".

Notification events are grouped into "categories." Examples of categories are: NF_HOSTPOSITION_UPDATED, NF_RADIOSTATE_CHANGED, NF_PP_TX_BEGIN, NF_PP_TX_END, NF_IPv4_ROUTINGTABLE_CHANGED, NF_BEACON_LOST NF_NODE_FAILURE, NF_NODE_RECOVERY, etc. Each category is identified by an integer (right now it's assigned in the source code via an enum, in the future we'll convert to dynamic category registration).

To trigger a notification, the client must obtain a pointer to the NotificationBoard of the given host or router (explained later), and call its fireChangeNotification() method. The notification will be delivered to all subscribed clients immediately, inside the fireChangeNotification() call.

Clients that wish to receive notifications should implement (subclass from) the INotifiable interface, obtain a pointer to the NotificationBoard, and subscribe to the categories they are interested in by calling the subscribe() method of the NotificationBoard. Notifications will be delivered to the receiveChangeNotification() method of the client (redefined from INotifiable).

In cases when the category itself (an int) does not carry enough information about the notification event, one can pass additional information in a data class. There is no restriction on what the data class may contain, except that it has to be subclassed from cPolymorphic, and of course producers and consumers of notifications should agree on its contents. If no extra info is needed, one can pass a NULL pointer in the fireChangeNotification() method.

A module which implements INotifiable looks like this:

 class Foo : public cSimpleModule, public INotifiable {
     ...
     virtual void receiveChangeNotification(int category, cPolymorphic *details) {..}
     ...
 };
 

Obtaining a pointer to the NotificationBoard module of that host/router:

 NotificationBoard *nb; // this is best made a module class member
 nb = NotificationBoardAccess().get();  // best done in initialize()
 

See NED file for additional info.

See also:
INotifiable
Author:
Andras Varga


Public Types

typedef std::vector< INotifiable * > NotifiableVector
typedef std::map< int, NotifiableVectorClientMap

Public Member Functions

Methods for consumers of change notifications
void subscribe (INotifiable *client, int category)
void unsubscribe (INotifiable *client, int category)
Methods for producers of change notifications
void fireChangeNotification (int category, cPolymorphic *details=NULL)

Protected Member Functions

virtual void initialize ()
virtual void handleMessage (cMessage *msg)

Protected Attributes

ClientMap clientMap

Friends

std::ostream & operator<< (std::ostream &, const NotifiableVector &)


Member Typedef Documentation

typedef std::map<int, NotifiableVector> NotificationBoard::ClientMap
 

typedef std::vector<INotifiable *> NotificationBoard::NotifiableVector
 


Member Function Documentation

void NotificationBoard::fireChangeNotification int  category,
cPolymorphic *  details = NULL
 

Tells NotificationBoard that a change of the given category has taken place. The optional details object may carry more specific information about the change (e.g. exact location, specific attribute that changed, old value, new value, etc).

00088 {
00089     Enter_Method("fireChangeNotification(%s, %s)", notificationCategoryName(category),
00090                  details?details->info().c_str() : "n/a");
00091 
00092     ClientMap::iterator it = clientMap.find(category);
00093     if (it==clientMap.end())
00094         return;
00095     NotifiableVector& clients = it->second;
00096     for (NotifiableVector::iterator j=clients.begin(); j!=clients.end(); j++)
00097         (*j)->receiveChangeNotification(category, details);
00098 }

void NotificationBoard::handleMessage cMessage *  msg  )  [protected, virtual]
 

Does nothing.

00057 {
00058     error("NotificationBoard doesn't handle messages, it can be accessed via direct method calls");
00059 }

void NotificationBoard::initialize  )  [protected, virtual]
 

Initialize.

00052 {
00053     WATCH_MAP(clientMap);
00054 }

void NotificationBoard::subscribe INotifiable client,
int  category
 

Subscribe to changes of the given category

00063 {
00064     Enter_Method("subscribe(%s)", notificationCategoryName(category));
00065 
00066     // find or create entry for this category
00067     NotifiableVector& clients = clientMap[category];
00068 
00069     // add client if not already there
00070     if (std::find(clients.begin(), clients.end(), client) == clients.end())
00071         clients.push_back(client);
00072 }

void NotificationBoard::unsubscribe INotifiable client,
int  category
 

Unsubscribe from changes of the given category

00075 {
00076     Enter_Method("unsubscribe(%s)", notificationCategoryName(category));
00077 
00078     // find (or create) entry for this category
00079     NotifiableVector& clients = clientMap[category];
00080 
00081     // remove client if there
00082     NotifiableVector::iterator it = std::find(clients.begin(), clients.end(), client);
00083     if (it!=clients.end())
00084         clients.erase(it);
00085 }


Friends And Related Function Documentation

std::ostream& operator<< std::ostream &  os,
const NotifiableVector v
[friend]
 

00027 {
00028     os << v.size() << " client(s)";
00029     for (unsigned int i=0; i<v.size(); i++)
00030     {
00031         os << (i==0 ? ": " : ", ");
00032         if (dynamic_cast<cModule*>(v[i]))
00033         {
00034             cModule *mod = dynamic_cast<cModule*>(v[i]);
00035             os << "mod (" << mod->className() << ")" << mod->fullName() << " id=" << mod->id();
00036         }
00037         else if (dynamic_cast<cPolymorphic*>(v[i]))
00038         {
00039             cPolymorphic *obj = dynamic_cast<cPolymorphic*>(v[i]);
00040             os << "a " << obj->className();
00041         }
00042         else
00043         {
00044             os << "a " << opp_typename(typeid(v[i]));
00045         }
00046     }
00047     return os;
00048 }


Member Data Documentation

ClientMap NotificationBoard::clientMap [protected]
 


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:27 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0