Sirikata
libcore/include/sirikata/core/util/ListenerProvider.hpp
Go to the documentation of this file.
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