00001 #ifndef PHX_LISTENERS_H
00002 #define PHX_LISTENERS_H
00003
00011 #include <map>
00012 #include <Phx/PhxConfig.h>
00013 #include <Phx/PhxTypes.h>
00014
00015 namespace Phx {
00016
00081 template <class Notifier, class Listener>
00082 class BaseListener : public LockedPtrInterface<BaseListener<Notifier, Listener> > {
00083 public:
00084 class Manager;
00085
00089 BaseListener(void) : mNotifier(0) {
00090 }
00091
00095 virtual ~BaseListener(void) {
00096 if (mNotifier) {
00097 std::clog << "Deleting a listener without uninstalling." << std::endl;
00098 }
00099 }
00100
00101 protected:
00102
00125 Notifier* notifier(void) { return mNotifier; }
00126
00127 private:
00128
00129 BaseListener(BaseListener<Notifier, Listener>&);
00130 BaseListener<Notifier, Listener>&
00131 operator=(BaseListener<Notifier, Listener>&);
00132
00133 friend class Manager;
00134 void setNotifier(Notifier* notifier) {
00135 mNotifier = notifier;
00136 }
00137
00138 Notifier* mNotifier;
00139 };
00140
00150 template<class Notifier, class Listener>
00151 class BaseListener<Notifier, Listener>::Manager {
00152 typedef BaseListener<Notifier, Listener> BaseListener;
00153 public:
00154
00163 Manager(Notifier* notifier) : mListener(0), mNotifier(notifier) {
00164 if (mNotifier == 0) {
00165 std::clog << "Cannot create listener "
00166 << "manager without notifier." << std::endl;
00167 throw InternalException();
00168 }
00169 }
00170
00171 virtual ~Manager() {
00172 if (mListener) {
00173
00174
00175
00176 ((BaseListener*)mListener)->setNotifier(0);
00177 }
00178 }
00179
00199 void listener(Listener* listener) {
00200
00201
00202 if (listener &&
00203 ((BaseListener*)listener)->notifier() != mNotifier &&
00204 ((BaseListener*)listener)->notifier() != 0) {
00205 std::clog << "Cannot install listener into a second notifier." << std::endl;
00206 throw PermissionException();
00207 }
00208
00209
00210 if (mListener) ((BaseListener*)mListener)->setNotifier(0);
00211
00212 if (listener) {
00213
00214 ((BaseListener*)listener)->setNotifier(mNotifier);
00215 }
00216
00217
00218 mListener = listener;
00219 }
00220
00228 Listener* listener(void) { return mListener; }
00229
00230 private:
00231
00232 Manager(Manager&);
00233 Manager& operator=(Manager&);
00234
00235 Listener* mListener;
00236 Notifier* mNotifier;
00237 };
00238
00239
00267 template <class Notifier, class Listener, class Selector>
00268 class BaseMultiListener : public LockedPtrInterface<BaseMultiListener<Notifier, Listener, Selector> > {
00269 public:
00270 class Manager;
00271
00272 BaseMultiListener(void) : mNotifier(0) {}
00273
00278 virtual ~BaseMultiListener(void) {
00279 if (mNotifier) {
00280 std::clog << "Deleting a multi-listener without uninstalling." << std::endl;
00281 }
00282 }
00283
00284 protected:
00297 Notifier* notifier(void) { return mNotifier; }
00298 const Notifier* notifier(void) const { return mNotifier; }
00299
00300 private:
00301
00302 BaseMultiListener(BaseMultiListener<Notifier, Listener, Selector>&);
00303 BaseMultiListener<Notifier, Listener, Selector>&
00304 operator=(BaseMultiListener<Notifier, Listener, Selector>&);
00305
00306 friend class Manager;
00307 void setNotifier(Notifier* notifier) {
00308 mNotifier = notifier;
00309 }
00310
00311 Notifier* mNotifier;
00312 };
00313
00318 template<class Notifier, class Listener, class Selector>
00319 class BaseMultiListener<Notifier, Listener, Selector>::Manager {
00320 public:
00321 typedef BaseMultiListener<Notifier, Listener, Selector> BaseListener;
00322 typedef std::map<Selector, Listener*> ListenerMapType;
00323 typedef typename ListenerMapType::iterator Iterator;
00324 typedef typename ListenerMapType::value_type ValueType;
00325
00330 Manager(Notifier* notifier) : mNotifier(notifier) {
00331 if (notifier == 0) {
00332 std::clog << "Cannot create multi-listener "
00333 << "manager without notifier." << std::endl;
00334 throw InternalException();
00335 }
00336 }
00337
00342 virtual ~Manager() {
00343 for (Iterator itr = begin(); itr != end(); ++itr) {
00344 if (itr->second) ((BaseListener*)(itr->second))->setNotifier(0);
00345 }
00346 }
00347
00348 Iterator begin() { return mListeners.begin(); }
00349 Iterator end() { return mListeners.end(); }
00350
00370 void listener(Selector selector, Listener* listener) {
00371
00372
00373
00374
00375 if (listener) {
00376
00377 if (((BaseListener*)listener)->notifier() != mNotifier &&
00378 ((BaseListener*)listener)->notifier() != 0) {
00379 std::clog << "Cannot install listener into a second notifier." << std::endl;
00380 throw PermissionException();
00381 }
00382
00383
00384 Manager::listener(selector, 0);
00385
00386
00387 ((BaseListener*)listener)->setNotifier(mNotifier);
00388
00389 mListeners.insert(ValueType(selector, listener));
00390 } else {
00391
00392 Iterator itr = mListeners.find(selector);
00393 if (itr != mListeners.end()) {
00394
00395 itr->second->setNotifier(0);
00396
00397 mListeners.erase(itr);
00398 }
00399 }
00400 }
00401
00411 Listener* listener(Selector selector) {
00412 Iterator itr = mListeners.find(selector);
00413 if (itr != mListeners.end()) {
00414 return itr->second;
00415 }
00416 return 0;
00417 }
00418
00419 private:
00420
00421 Manager(Manager&);
00422 Manager& operator=(Manager&);
00423
00424 ListenerMapType mListeners;
00425 Notifier* mNotifier;
00426 };
00427
00428 };
00429
00430 #endif