|
INET Framework for OMNeT++/OMNEST
|
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