signal_v0.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 "../api_core.h"
00035 #include "slot.h"
00036 #include "signals_impl.h"
00037 
00040 class CL_API_CORE CL_SlotCallback_v0 : public CL_SlotCallback
00041 {
00042 public:
00043         virtual void invoke() = 0;
00044 };
00045 
00048 class CL_API_CORE CL_SlotCallback_v0_static : public CL_SlotCallback_v0
00049 {
00050 public:
00051         CL_SlotCallback_v0_static(void (*static_func)())
00052         : static_func(static_func) { return; }
00053         void invoke() { static_func(); }
00054         void (*static_func)();
00055 };
00056 
00059 template <class UserData>
00060 class CL_SlotCallback_v0_static_user : public CL_SlotCallback_v0
00061 {
00062 public:
00063         CL_SlotCallback_v0_static_user(void (*static_func)(UserData), const UserData &user_data)
00064         : static_func(static_func), user_data(user_data) { return; }
00065         void invoke() { static_func(user_data); }
00066         void (*static_func)(UserData);
00067         UserData user_data;
00068 };
00069 
00072 template <class InstanceClass>
00073 class CL_SlotCallback_v0_member : public CL_SlotCallback_v0
00074 {
00075 public:
00076         CL_SlotCallback_v0_member(InstanceClass *instance, void (InstanceClass::*member_func)())
00077         : instance(instance), member_func(member_func) { return; }
00078         void invoke() { (instance->*member_func)(); }
00079         InstanceClass *instance;
00080         void (InstanceClass::*member_func)();
00081 };
00082 
00085 template <class InstanceClass, class UserData>
00086 class CL_SlotCallback_v0_member_user : public CL_SlotCallback_v0
00087 {
00088 public:
00089         CL_SlotCallback_v0_member_user(InstanceClass *instance, void (InstanceClass::*member_func)(UserData), const UserData &user_data)
00090         : instance(instance), member_func(member_func), user_data(user_data) { return; }
00091         void invoke() { (instance->*member_func)(user_data); }
00092         InstanceClass *instance;
00093         void (InstanceClass::*member_func)(UserData);
00094         UserData user_data;
00095 };
00096 
00099 template <class Functor>
00100 class CL_SlotCallback_v0_functor : public CL_SlotCallback_v0
00101 {
00102 public:
00103         CL_SlotCallback_v0_functor(const Functor &functor)
00104         : functor(functor) { return; }
00105         void invoke() { functor(); }
00106         Functor functor;
00107 };
00108 
00112 class CL_API_CORE CL_Signal_v0
00113 {
00116 
00117 public:
00118         CL_Signal_v0()
00119         : impl(new CL_Signal_Impl) { return; }
00120 
00121         CL_Signal_v0(const CL_Signal_v0 &copy)
00122         : impl(copy.impl) { return; }
00123 
00124 
00128 
00129 public:
00130         CL_Slot connect(void (*function)())
00131         {
00132                 clean_up();
00133                 CL_SharedPtr<CL_SlotCallback> callback(
00134                         new CL_SlotCallback_v0_static(function));
00135                 impl->connected_slots.push_back(callback);
00136                 return CL_Slot(callback);
00137         }
00138 
00139         template<class UserData>
00140         CL_Slot connect(void (*function)(UserData), const UserData &user_data)
00141         {
00142                 clean_up();
00143                 CL_SharedPtr<CL_SlotCallback> callback(
00144                         new CL_SlotCallback_v0_static_user<UserData>(function, user_data));
00145                 impl->connected_slots.push_back(callback);
00146                 return CL_Slot(callback);
00147         }
00148 
00149         template<class InstanceClass>
00150         CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)())
00151         {
00152                 clean_up();
00153                 CL_SharedPtr<CL_SlotCallback> callback(
00154                         new CL_SlotCallback_v0_member<InstanceClass>(instance, function));
00155                 impl->connected_slots.push_back(callback);
00156                 return CL_Slot(callback);
00157         }
00158 
00159         template<class InstanceClass, class UserData>
00160         CL_Slot connect(InstanceClass *instance, void (InstanceClass::*function)(UserData), const UserData &user_data)
00161         {
00162                 clean_up();
00163                 CL_SharedPtr<CL_SlotCallback> callback(
00164                         new CL_SlotCallback_v0_member_user<InstanceClass, UserData>(instance, function, user_data));
00165                 impl->connected_slots.push_back(callback);
00166                 return CL_Slot(callback);
00167         }
00168 
00169         template<class Functor>
00170         CL_Slot connect_functor(const Functor &functor)
00171         {
00172                 clean_up();
00173                 CL_SharedPtr<CL_SlotCallback> callback(
00174                         new CL_SlotCallback_v0_functor<Functor>(functor));
00175                 impl->connected_slots.push_back(callback);
00176                 return CL_Slot(callback);
00177         }
00178 
00179         void invoke() const
00180         {
00181                 std::vector< CL_SharedPtr<CL_SlotCallback> > callbacks = impl->connected_slots;
00182                 std::vector< CL_SharedPtr<CL_SlotCallback> >::size_type i, size;
00183                 size = callbacks.size();
00184                 for (i = 0; i < size; i++)
00185                         if (callbacks[i]->valid && callbacks[i]->enabled)
00186                                 ((CL_SlotCallback_v0 *) callbacks[i].get())->invoke();
00187         }
00188 
00189 
00193 
00194 private:
00195         void clean_up()
00196         {
00197                 std::vector< CL_SharedPtr<CL_SlotCallback> >::size_type i, size;
00198                 size = impl->connected_slots.size();
00199                 for (i = 0; i < size; i++)
00200                 {
00201                         if (!impl->connected_slots[i]->valid)
00202                         {
00203                                 impl->connected_slots.erase(impl->connected_slots.begin()+i);
00204                                 i--;
00205                                 size--;
00206                         }
00207                 }
00208         }
00209 
00210         CL_SharedPtr<CL_Signal_Impl> impl;
00212 };
00213 
00214