signal_v2.h

Go to the documentation of this file.
00001 /*
00002 **  ClanLib SDK
00003 **  Copyright (c) 1997-2011 The ClanLib Team
00004 **
00005 **  This software is provided 'as-is', without any express or implied
00006 **  warranty.  In no event will the authors be held liable for any damages
00007 **  arising from the use of this software.
00008 **
00009 **  Permission is granted to anyone to use this software for any purpose,
00010 **  including commercial applications, and to alter it and redistribute it
00011 **  freely, subject to the following restrictions:
00012 **
00013 **  1. The origin of this software must not be misrepresented; you must not
00014 **     claim that you wrote the original software. If you use this software
00015 **     in a product, an acknowledgment in the product documentation would be
00016 **     appreciated but is not required.
00017 **  2. Altered source versions must be plainly marked as such, and must not be
00018 **     misrepresented as being the original software.
00019 **  3. This notice may not be removed or altered from any source distribution.
00020 **
00021 **  Note: Some of the libraries ClanLib may link to may have additional
00022 **  requirements or restrictions.
00023 **
00024 **  File Author(s):
00025 **
00026 **    Magnus Norddahl
00027 */
00028 
00031 
00032 #pragma once
00033 
00034 #include "slot.h"
00035 #include "signals_impl.h"
00036 
00039 template <class Param1, class Param2>
00040 class CL_SlotCallback_v2 : public CL_SlotCallback
00041 {
00042 public:
00043         virtual void invoke(Param1 param1, Param2 param2) = 0;
00044 };
00045 
00048 template <class Param1, class Param2>
00049 class CL_SlotCallback_v2_static : public CL_SlotCallback_v2<Param1, Param2>
00050 {
00051 public:
00052         CL_SlotCallback_v2_static(void (*static_func)(Param1, Param2))
00053         : static_func(static_func) { return; }
00054         void invoke(Param1 param1, Param2 param2) { static_func(param1, param2); }
00055         void (*static_func)(Param1, Param2);
00056 };
00057 
00060 template <class Param1, class Param2, class UserData>
00061 class CL_SlotCallback_v2_static_user : public CL_SlotCallback_v2<Param1, Param2>
00062 {
00063 public:
00064         CL_SlotCallback_v2_static_user(void (*static_func)(Param1, Param2, UserData), const UserData &user_data)
00065         : static_func(static_func), user_data(user_data) { return; }
00066         void invoke(Param1 param1, Param2 param2) { static_func(param1, param2, user_data); }
00067         void (*static_func)(Param1, Param2, UserData);
00068         UserData user_data;
00069 };
00070 
00073 template <class Param1, class Param2, class InstanceClass>
00074 class CL_SlotCallback_v2_member : public CL_SlotCallback_v2<Param1, Param2>
00075 {
00076 public:
00077         CL_SlotCallback_v2_member(InstanceClass *instance, void (InstanceClass::*member_func)(Param1, Param2))
00078         : instance(instance), member_func(member_func) { return; }
00079         void invoke(Param1 param1, Param2 param2) { (instance->*member_func)(param1, param2); }
00080         InstanceClass *instance;
00081         void (InstanceClass::*member_func)(Param1, Param2);
00082 };
00083 
00086 template <class Param1, class Param2, class InstanceClass, class UserData>
00087 class CL_SlotCallback_v2_member_user : public CL_SlotCallback_v2<Param1, Param2>
00088 {
00089 public:
00090         CL_SlotCallback_v2_member_user(InstanceClass *instance, void (InstanceClass::*member_func)(Param1, Param2, UserData), const UserData &user_data)
00091         : instance(instance), member_func(member_func), user_data(user_data) { return; }
00092         void invoke(Param1 param1, Param2 param2) { (instance->*member_func)(param1, param2, user_data); }
00093         InstanceClass *instance;
00094         void (InstanceClass::*member_func)(Param1, Param2, UserData);
00095         UserData user_data;
00096 };
00097 
00100 template <class Param1, class Param2, class Functor>
00101 class CL_SlotCallback_v2_functor : public CL_SlotCallback_v2<Param1, Param2>
00102 {
00103 public:
00104         CL_SlotCallback_v2_functor(const Functor &functor)
00105         : functor(functor) { return; }
00106         void invoke(Param1 param1, Param2 param2) { functor(param1, param2); }
00107         Functor functor;
00108 };
00109 
00113 template <class Param1, class Param2>
00114 class CL_Signal_v2
00115 {
00118 
00119 public:
00120         CL_Signal_v2()
00121         : impl(new CL_Signal_Impl) { return; }
00122 
00123         CL_Signal_v2(const CL_Signal_v2<Param1, Param2> &copy)
00124         : impl(copy.impl) { return; }
00125 
00126 
00130 
00131 public:
00132         CL_Slot connect(void (*function)(Param1, Param2))
00133         {
00134                 clean_up();
00135                 CL_SharedPtr<CL_SlotCallback> callback(
00136                         new CL_SlotCallback_v2_static<Param1, Param2>(function));
00137                 impl->connected_slots.push_back(callback);
00138                 return CL_Slot(callback);
00139         }
00140 
00141         template<class UserData>
00142         CL_Slot connect(void (*function)(Param1, Param2, UserData), const UserData &user_data)
00143         {
00144                 clean_up();
00145                 CL_SharedPtr<CL_SlotCallback> callback(
00146                         new CL_SlotCallback_v2_static_user<Param1, Param2, UserData>(function, user_data));
00147                 impl->connected_slots.push_back(callback);
00148                 return CL_Slot(callback);
00149         }
00150 
00151         template<class InstanceClass>
00152         CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(Param1, Param2))
00153         {
00154                 clean_up();
00155                 CL_SharedPtr<CL_SlotCallback> callback(
00156                         new CL_SlotCallback_v2_member<Param1, Param2, InstanceClass>(instance, function));
00157                 impl->connected_slots.push_back(callback);
00158                 return CL_Slot(callback);
00159         }
00160 
00161         template<class InstanceClass, class UserData>
00162         CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(Param1, Param2, UserData), const UserData &user_data)
00163         {
00164                 clean_up();
00165                 CL_SharedPtr<CL_SlotCallback> callback(
00166                         new CL_SlotCallback_v2_member_user<Param1, Param2, InstanceClass, UserData>(instance, function, user_data));
00167                 impl->connected_slots.push_back(callback);
00168                 return CL_Slot(callback);
00169         }
00170 
00171         template<class Functor>
00172         CL_Slot connect_functor(const Functor &functor)
00173         {
00174                 clean_up();
00175                 CL_SharedPtr<CL_SlotCallback> callback(
00176                         new CL_SlotCallback_v2_functor<Param1, Param2, Functor>(functor));
00177                 impl->connected_slots.push_back(callback);
00178                 return CL_Slot(callback);
00179         }
00180 
00181         void invoke(Param1 param1, Param2 param2) const
00182         {
00183                 std::vector< CL_SharedPtr<CL_SlotCallback> > callbacks = impl->connected_slots;
00184                 std::vector< CL_SharedPtr<CL_SlotCallback> >::size_type i, size;
00185                 size = callbacks.size();
00186                 for (i = 0; i < size; i++)
00187                         if (callbacks[i]->valid && callbacks[i]->enabled)
00188                                 ((CL_SlotCallback_v2<Param1, Param2> *) callbacks[i].get())->invoke(param1, param2);
00189         }
00190 
00191 
00195 
00196 private:
00197         void clean_up()
00198         {
00199                 std::vector< CL_SharedPtr<CL_SlotCallback> >::size_type i, size;
00200                 size = impl->connected_slots.size();
00201                 for (i = 0; i < size; i++)
00202                 {
00203                         if (!impl->connected_slots[i]->valid)
00204                         {
00205                                 impl->connected_slots.erase(impl->connected_slots.begin()+i);
00206                                 i--;
00207                                 size--;
00208                         }
00209                 }
00210         }
00211 
00212         CL_SharedPtr<CL_Signal_Impl> impl;
00214 };
00215 
00216