NotificationBoard.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005 Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 
00019 #include <algorithm>
00020 #include "NotificationBoard.h"
00021 #include "NotifierConsts.h"
00022 
00023 Define_Module(NotificationBoard);
00024 
00025 std::ostream& operator<<(std::ostream& os, const NotificationBoard::NotifiableVector& v)
00026 {
00027     os << v.size() << " client(s)";
00028     for (unsigned int i=0; i<v.size(); i++)
00029     {
00030         os << (i==0 ? ": " : ", ");
00031         if (dynamic_cast<cModule*>(v[i]))
00032         {
00033             cModule *mod = dynamic_cast<cModule*>(v[i]);
00034             os << "mod (" << mod->getClassName() << ")" << mod->getFullName() << " id=" << mod->getId();
00035         }
00036         else if (dynamic_cast<cPolymorphic*>(v[i]))
00037         {
00038             cPolymorphic *obj = dynamic_cast<cPolymorphic*>(v[i]);
00039             os << "a " << obj->getClassName();
00040         }
00041         else
00042         {
00043             os << "a " << opp_typename(typeid(v[i]));
00044         }
00045     }
00046     return os;
00047 }
00048 
00049 
00050 void NotificationBoard::initialize()
00051 {
00052     WATCH_MAP(clientMap);
00053 }
00054 
00055 void NotificationBoard::handleMessage(cMessage *msg)
00056 {
00057     error("NotificationBoard doesn't handle messages, it can be accessed via direct method calls");
00058 }
00059 
00060 
00061 void NotificationBoard::subscribe(INotifiable *client, int category)
00062 {
00063     Enter_Method("subscribe(%s)", notificationCategoryName(category));
00064 
00065     // find or create entry for this category
00066     NotifiableVector& clients = clientMap[category];
00067 
00068     // add client if not already there
00069     if (std::find(clients.begin(), clients.end(), client) == clients.end())
00070         clients.push_back(client);
00071 
00072     fireChangeNotification(NF_SUBSCRIBERLIST_CHANGED, NULL);
00073 }
00074 
00075 void NotificationBoard::unsubscribe(INotifiable *client, int category)
00076 {
00077     Enter_Method("unsubscribe(%s)", notificationCategoryName(category));
00078 
00079     // find (or create) entry for this category
00080     NotifiableVector& clients = clientMap[category];
00081 
00082     // remove client if there
00083     NotifiableVector::iterator it = std::find(clients.begin(), clients.end(), client);
00084     if (it!=clients.end())
00085         clients.erase(it);
00086 
00087     fireChangeNotification(NF_SUBSCRIBERLIST_CHANGED, NULL);
00088 }
00089 
00090 bool NotificationBoard::hasSubscribers(int category)
00091 {
00092     ClientMap::iterator it = clientMap.find(category);
00093     return it!=clientMap.end() && !it->second.empty();
00094 }
00095 
00096 void NotificationBoard::fireChangeNotification(int category, const cPolymorphic *details)
00097 {
00098     Enter_Method("fireChangeNotification(%s, %s)", notificationCategoryName(category),
00099                  details?details->info().c_str() : "n/a");
00100 
00101     ClientMap::iterator it = clientMap.find(category);
00102     if (it==clientMap.end())
00103         return;
00104     NotifiableVector& clients = it->second;
00105     for (NotifiableVector::iterator j=clients.begin(); j!=clients.end(); j++)
00106         (*j)->receiveChangeNotification(category, details);
00107 }
00108 
00109