00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "ObjectClassBroadcastList.hh"
00025 #include "InteractionBroadcastList.hh"
00026 #include "RTIRegion.hh"
00027 #include "Subscribable.hh"
00028 #include "helper.hh"
00029 #include "PrettyDebug.hh"
00030
00031 #include <algorithm>
00032
00033 namespace {
00034
00035 PrettyDebug D("SUBSCRIBABLE", __FILE__);
00036
00037 }
00038
00039 namespace certi {
00040
00041
00042
00043 Subscriber::Subscriber(FederateHandle h)
00044 : handle(h), region(0)
00045 {
00046 }
00047
00048
00049
00050 Subscriber::Subscriber(FederateHandle h, const RTIRegion *r)
00051 : handle(h), region(r)
00052 {
00053 }
00054
00055
00056 FederateHandle
00057 Subscriber::getHandle() const
00058 {
00059 return handle ;
00060 }
00061
00062
00063 const RTIRegion *
00064 Subscriber::getRegion() const
00065 {
00066 return region ;
00067 }
00068
00069
00070 bool
00071 Subscriber::operator==(const Subscriber &sub) const
00072 {
00073 return (handle == sub.getHandle()) && (region == sub.getRegion());
00074 }
00075
00076
00077 bool
00078 Subscriber::equals(FederateHandle fed, const RTIRegion *r) const
00079 {
00080 return handle == fed && region == r ;
00081 }
00082
00083
00088 bool
00089 Subscriber::match(const RTIRegion *r) const
00090 {
00091 D[pdTrace] << "Match test: " << (region ? region->getHandle() : 0) << " vs "
00092 << (r ? r->getHandle() : 0) << std::endl ;
00093 return (region == 0) || (r == 0) || region->overlaps(*r);
00094 }
00095
00096
00097 Subscribable::~Subscribable()
00098 {
00099 if (!subscribers.empty())
00100 D[pdError] << "Subscribers list not empty at termination." << std::endl ;
00101 }
00102
00103
00107 void
00108 Subscribable::unsubscribe(FederateHandle fed)
00109 {
00110 std::remove_if(subscribers.begin(),
00111 subscribers.end(),
00112 HandleComparator<Subscriber>(fed));
00113 }
00114
00115
00120 void
00121 Subscribable::unsubscribe(FederateHandle fed, const RTIRegion *region)
00122 {
00123 subscribers.remove(Subscriber(fed, region));
00124 }
00125
00126
00132 bool
00133 Subscribable::isSubscribed(FederateHandle fed,
00134 const RTIRegion *region) const
00135 {
00136 return std::find(subscribers.begin(),
00137 subscribers.end(),
00138 Subscriber(fed, region)) != subscribers.end();
00139 }
00140
00141
00146 bool
00147 Subscribable::isSubscribed(FederateHandle fed) const
00148 {
00149 return std::find_if(subscribers.begin(),
00150 subscribers.end(),
00151 HandleComparator<Subscriber>(fed)) != subscribers.end();
00152 }
00153
00154
00159 void
00160 Subscribable::subscribe(FederateHandle fed, const RTIRegion *region)
00161 {
00162 if (!isSubscribed(fed, region)) {
00163 checkFederateAccess(fed, "Subscribe");
00164 subscribers.push_back(Subscriber(fed, region));
00165 }
00166 else
00167 D[pdError] << "Inconsistency in subscribe request from federate "
00168 << fed << std::endl ;
00169 }
00170
00171
00177 void
00178 Subscribable::addFederatesIfOverlap(ObjectClassBroadcastList &lst, const RTIRegion *region, Handle handle) const
00179 {
00180 std::list<Subscriber>::const_iterator it = subscribers.begin();
00181 for (; it != subscribers.end(); ++it) {
00182 if (it->match(region))
00183 lst.addFederate(it->getHandle(), handle);
00184 }
00185 }
00186
00187
00192 void
00193 Subscribable::addFederatesIfOverlap(InteractionBroadcastList &lst, const RTIRegion *region) const
00194 {
00195 std::list<Subscriber>::const_iterator it = subscribers.begin();
00196 for (; it != subscribers.end(); ++it) {
00197 if (it->match(region))
00198 lst.addFederate(it->getHandle());
00199 }
00200 }
00201
00202 }
00203
00204