Sirikata
|
00001 /* Sirikata Utilities -- Sirikata Listener Pattern 00002 * ListenerProvider.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef _SIRIKATA_LISTENER_PROVIDER_HPP_ 00033 #define _SIRIKATA_LISTENER_PROVIDER_HPP_ 00034 00035 00036 namespace Sirikata { 00041 template <typename ListenerPtr> class Provider { 00042 protected: 00043 typedef std::vector<ListenerPtr> ListenerVector; 00044 typedef std::map<ListenerPtr,uint32> ListenerMap; 00046 ListenerVector mListeners; 00048 ListenerMap mListenerIndex; 00049 virtual ~Provider(){} 00051 virtual void listenerAdded(ListenerPtr ){} 00053 virtual void listenerRemoved(ListenerPtr ){} 00055 virtual void firstListenerAdded(ListenerPtr ){} 00057 virtual void lastListenerRemoved(ListenerPtr ){} 00063 template <typename T> void notify(T func){ 00064 for (int32 i=(int32)mListeners.size()-1; 00065 i>=0&&i<(int32)mListeners.size(); 00066 --i) { 00067 ((&*mListeners[i])->*func)(); 00068 } 00069 } 00075 template <typename T, typename A> void notify(T func, A newA){ 00076 for (int32 i=(int32)mListeners.size()-1; 00077 i>=0&&i<(int32)mListeners.size(); 00078 --i) { 00079 ((&*mListeners[i])->*func)(newA); 00080 } 00081 } 00089 template <typename T, typename A, typename B> 00090 void notify(T func, A newA, B newB){ 00091 for (int32 i=(int32)mListeners.size()-1; 00092 i>=0&&i<(int32)mListeners.size(); 00093 --i) { 00094 ((&*mListeners[i])->*func)(newA,newB); 00095 } 00096 } 00106 template <typename T, typename A, typename B, typename C> 00107 void notify(T func, A newA, B newB, C newC){ 00108 for (int32 i=(int32)mListeners.size()-1; 00109 i>=0&&i<(int32)mListeners.size(); 00110 --i) { 00111 ((&*mListeners[i])->*func)(newA,newB,newC); 00112 } 00113 } 00124 template <typename T, typename A, typename B, typename C, typename D> 00125 void notify(T func, A newA, B newB, C newC, D newD){ 00126 for (int32 i=(int32)mListeners.size()-1; 00127 i>=0&&i<(int32)mListeners.size(); 00128 --i) { 00129 ((&*mListeners[i])->*func)(newA,newB,newC,newD); 00130 } 00131 } 00143 template <typename T, typename A, typename B, typename C, typename D, typename E> 00144 void notify(T func, A newA, B newB, C newC, D newD, E newE){ 00145 for (int32 i=(int32)mListeners.size()-1; 00146 i>=0&&i<(int32)mListeners.size(); 00147 --i) { 00148 ((&*mListeners[i])->*func)(newA,newB,newC,newD,newE); 00149 } 00150 } 00163 template <typename T, typename A, typename B, typename C, typename D, typename E, typename F> 00164 void notify(T func, A newA, B newB, C newC, D newD, E newE, F newF){ 00165 for (int32 i=(int32)mListeners.size()-1; 00166 i>=0&&i<(int32)mListeners.size(); 00167 --i) { 00168 ((&*mListeners[i])->*func)(newA,newB,newC,newD,newE,newF); 00169 } 00170 } 00171 00185 template <typename T, typename A, typename B, typename C, typename D, typename E, typename F, typename G> 00186 void notify(T func, A newA, B newB, C newC, D newD, E newE, F newF, G newG){ 00187 for (int32 i=(int32)mListeners.size()-1; 00188 i>=0&&i<(int32)mListeners.size(); 00189 --i) { 00190 ((&*mListeners[i])->*func)(newA,newB,newC,newD,newE,newF,newG); 00191 } 00192 } 00193 00208 template <typename T, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> 00209 void notify(T func, A newA, B newB, C newC, D newD, E newE, F newF, G newG, H newH){ 00210 for (int32 i=(int32)mListeners.size()-1; 00211 i>=0&&i<(int32)mListeners.size(); 00212 --i) { 00213 ((&*mListeners[i])->*func)(newA,newB,newC,newD,newE,newF,newG,newH); 00214 } 00215 } 00216 00232 template <typename T, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> 00233 void notify(T func, A newA, B newB, C newC, D newD, E newE, F newF, G newG, H newH, I newI){ 00234 for (int32 i=(int32)mListeners.size()-1; 00235 i>=0&&i<(int32)mListeners.size(); 00236 --i) { 00237 ((&*mListeners[i])->*func)(newA,newB,newC,newD,newE,newF,newG,newH,newI); 00238 } 00239 } 00240 00241 00242 public: 00247 virtual void addListener(ListenerPtr p) { 00248 if (mListeners.empty()) { 00249 mListeners.push_back(p); 00250 this->firstListenerAdded(p); 00251 }else if (mListeners.size()==1) { 00252 mListenerIndex[mListeners[0]]=0; 00253 mListenerIndex[p]=1; 00254 mListeners.push_back(p); 00255 }else { 00256 mListenerIndex[p]=mListeners.size(); 00257 mListeners.push_back(p); 00258 } 00259 this->listenerAdded(p); 00260 } 00265 virtual void removeListener(ListenerPtr p) { 00266 this->listenerRemoved(p); 00267 if (mListeners.size()>1) { 00268 typename ListenerMap::iterator where=mListenerIndex.find(p); 00269 assert(where!=mListenerIndex.end()); 00270 if (where->second+1!=mListeners.size()) { 00271 mListenerIndex[mListeners.back()]=where->second; 00272 mListeners[where->second]=mListeners.back(); 00273 } 00274 mListeners.resize(mListeners.size()-1); 00275 mListenerIndex.erase(where); 00276 }else { 00277 this->lastListenerRemoved(p); 00278 assert(mListeners[0]==p); 00279 mListeners.resize(0); 00280 mListenerIndex=ListenerMap(); 00281 } 00282 } 00283 }; 00284 00285 } 00286 #endif