00001 /* 00002 Copyright (c) 2010, The Cinder Project (http://libcinder.org) 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00006 the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00009 the following disclaimer. 00010 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00011 the following disclaimer in the documentation and/or other materials provided with the distribution. 00012 00013 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00014 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00015 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00016 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00017 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00018 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00019 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00020 POSSIBILITY OF SUCH DAMAGE. 00021 */ 00022 00023 #pragma once 00024 00025 #include "cinder/Cinder.h" 00026 00027 #include <algorithm> 00028 #include <vector> 00029 #include <utility> 00030 00031 #if defined( _MSC_VER ) && ( _MSC_VER >= 1600 ) 00032 #include <functional> 00033 #elif defined( CINDER_COCOA ) 00034 #include <tr1/functional> 00035 #else 00036 #include <boost/tr1/functional.hpp> 00037 #endif 00038 namespace std { 00039 using std::tr1::function; 00040 using std::tr1::bind; 00041 using namespace std::tr1::placeholders; 00042 } 00043 00044 namespace cinder { 00045 00047 typedef uint32_t CallbackId; 00048 00050 template<typename SIG> 00051 class CallbackMgr { 00052 public: 00053 typedef typename std::vector<std::pair<CallbackId,std::function<SIG> > > collection; 00054 typedef typename collection::iterator iterator; 00055 00056 CallbackId registerCb( std::function<SIG> cb ) 00057 { 00058 CallbackId cbId = 0; 00059 if( ! mCallbacks.empty() ) 00060 cbId = mCallbacks.rbegin()->first + 1; 00061 mCallbacks.push_back( std::make_pair( cbId, cb ) ); 00062 return cbId; 00063 } 00064 00065 CallbackId registerCb( iterator position, std::function<SIG> cb ) 00066 { 00067 CallbackId cbId = 0; 00068 if( ! mCallbacks.empty() ) 00069 cbId = mCallbacks.rbegin()->first + 1; 00070 mCallbacks.insert( position, std::make_pair( cbId, cb ) ); 00071 return cbId; 00072 } 00073 00074 template<typename A1> 00075 void call( A1 a1 ) { for( iterator it = begin(); it != end(); ++it ) it->second( a1 ); } 00076 template<typename A1, typename A2> 00077 void call( A1 a1, A2 a2 ) { for( iterator it = begin(); it != end(); ++it ) it->second( a1, a2 ); } 00078 template<typename A1, typename A2, typename A3> 00079 void call( A1 a1, A2 a2, A3 a3 ) { for( iterator it = begin(); it != end(); ++it ) it->second( a1, a2, a3 ); } 00080 template<typename A1, typename A2, typename A3, typename A4> 00081 void call( A1 a1, A2 a2, A3 a3, A4 a4 ) { for( iterator it = begin(); it != end(); ++it ) it->second( a1, a2, a3, a4 ); } 00082 template<typename A1, typename A2, typename A3, typename A4, typename A5> 00083 void call( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ) { for( iterator it = begin(); it != end(); ++it ) it->second( a1, a2, a3, a4, a5 ); } 00084 00085 void unregisterCb( CallbackId cbId ) { mCallbacks.erase( find( cbId ) ); } 00086 00087 bool empty() const { return mCallbacks.empty(); } 00088 00089 iterator find( CallbackId cbId ) { for( iterator it = begin(); it != end(); ++it ) if( it->first == cbId ) return it; return mCallbacks.end(); } 00090 iterator begin() { return mCallbacks.begin(); } 00091 iterator end() { return mCallbacks.end(); } 00092 00093 collection& getCallbacks() { return mCallbacks; } 00094 00095 private: 00096 collection mCallbacks; 00097 }; 00098 00099 } // namespace cinder