/home/tetron/hack/vos/libs/vos/vutil/listener.hh
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _VUTIL_LISTENER_HH_
00024 #define _VUTIL_LISTENER_HH_
00025
00026
00027
00028
00029
00030 #include <vos/vutil/vutildefs.hh>
00031 #include <vos/vutil/refcount.hh>
00032 #include <vos/vutil/taskqueue.hh>
00033
00034 #include <string>
00035
00036 namespace VUtil
00037 {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 template<class Listener, class Event> class ListenerTask : public Task
00052 {
00053 private:
00054 Listener* l;
00055 vRef<Event> e;
00056
00057 public:
00058
00059
00060
00061
00062 ListenerTask(Listener* li, Event* ev) : l(li), e(ev, true) {
00063 if(RefCounted* rc = dynamic_cast<RefCounted*>(l)) {
00064 rc->acquire();
00065 }
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075 virtual void doTask() {
00076 e->deliverTo(l);
00077 }
00078
00079
00080 virtual ~ListenerTask() {
00081 if(RefCounted* rc = dynamic_cast<RefCounted*>(l)) {
00082 rc->release();
00083 }
00084 }
00085 };
00086
00087
00088
00089
00090
00091
00092
00093
00094 template<class Listener, class Event> class ListenerBase : public ObjectExciseListener
00095 {
00096 private:
00097 boost::mutex listeners_mutex;
00098 std::set<Listener*> listeners;
00099 bool inClear;
00100 bool async;
00101
00102 public:
00103
00104 ListenerBase() : async(true) { }
00105
00106
00107 virtual ~ListenerBase() {
00108 clearListeners();
00109 }
00110
00111
00112
00113
00114
00115
00116 void addListener(Listener* l) {
00117 boost::mutex::scoped_lock lk(listeners_mutex);
00118
00119 if(listeners.count(l) == 0) {
00120 if(RefCounted* rc = dynamic_cast<RefCounted*>(l)) {
00121 rc->acquire();
00122 rc->addExciseListener(this);
00123 }
00124 listeners.insert(l);
00125 }
00126 }
00127
00128
00129
00130
00131
00132 void removeListener(Listener* l) {
00133 if(! inClear) {
00134 boost::mutex::scoped_lock lk(listeners_mutex);
00135
00136 if(listeners.count(l) > 0) {
00137 listeners.erase(l);
00138 if(RefCounted* rc = dynamic_cast<RefCounted*>(l)) {
00139 rc->removeExciseListener(this);
00140 rc->release();
00141 }
00142 }
00143 }
00144 }
00145
00146
00147
00148
00149 void clearListeners() {
00150 boost::mutex::scoped_lock lk(listeners_mutex);
00151 inClear = true;
00152
00153 for(typename std::set<Listener*>::iterator i = listeners.begin();
00154 i != listeners.end();
00155 i++)
00156 {
00157 if(RefCounted* rc = dynamic_cast<RefCounted*>(*i)) {
00158 rc->removeExciseListener(this);
00159 rc->release();
00160 }
00161 }
00162 listeners.clear();
00163
00164 inClear = false;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 void distributeEvent(Event* e) {
00177 boost::mutex::scoped_lock lk(listeners_mutex);
00178
00179 if (async) {
00180 for(typename std::set<Listener*>::iterator i = listeners.begin();
00181 i != listeners.end();
00182 i++)
00183 {
00184 TaskQueue::defaultTQ().addTask(new ListenerTask<Listener, Event>(*i, e));
00185 }
00186 } else {
00187 std::set<Listener*> templisteners = listeners;
00188
00189 lk.unlock();
00190
00191 for(typename std::set<Listener*>::iterator i = templisteners.begin();
00192 i != templisteners.end();
00193 i++)
00194 {
00195 e->deliverTo(*i);
00196 }
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 void notifyObjectExcise(RefCounted* object) {
00207 if(Listener* l = dynamic_cast<Listener*>(object)) {
00208 removeListener(l);
00209 }
00210 }
00211
00212
00213 unsigned int listenerCount() {
00214 boost::mutex::scoped_lock lk(listeners_mutex);
00215 return listeners.size();
00216 }
00217
00218
00219
00220
00221
00222 bool hasListener(Listener* l) {
00223 boost::mutex::scoped_lock lk(listeners_mutex);
00224 return (listeners.count(l) > 0);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 bool getAsynchronousEvents() {
00236 return async;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 void setAsynchronousEvents(bool b) {
00248 async = b;
00249 }
00250 };
00251 }
00252
00253 #endif