CEGUIEvent.h

00001 /************************************************************************
00002         filename: CEGUIEvent.h
00003         created:  15/10/2004
00004         authors:  Paul D Turner (High-level design) 
00005             Gerald Lindsly (Coder)
00006         
00007         purpose:  Defines interface for Event class
00008 *************************************************************************/
00009 /*************************************************************************
00010     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00011     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00012 
00013     This library is free software; you can redistribute it and/or
00014     modify it under the terms of the GNU Lesser General Public
00015     License as published by the Free Software Foundation; either
00016     version 2.1 of the License, or (at your option) any later version.
00017 
00018     This library is distributed in the hope that it will be useful,
00019     but WITHOUT ANY WARRANTY; without even the implied warranty of
00020     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021     Lesser General Public License for more details.
00022 
00023     You should have received a copy of the GNU Lesser General Public
00024     License along with this library; if not, write to the Free Software
00025     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 *************************************************************************/
00027 #ifndef _CEGUIEvent_h_
00028 #define _CEGUIEvent_h_
00029 
00030 #if defined (_MSC_VER)
00031 #       pragma warning(push)
00032 #       pragma warning(disable : 4786)
00033 #       pragma warning(disable : 4251)
00034 #       if !defined (_MSC_EXTENSIONS)
00035 #               pragma warning (disable : 4224)
00036 #       endif
00037 #endif
00038 
00039 #include "CEGUIBase.h"
00040 #include "CEGUIString.h"
00041 #include "CEGUIEventArgs.h"
00042 #include "CEGUIRefPtr.h"
00043 
00044 #include <map>
00045 
00046 
00047 // Start of CEGUI namespace section
00048 namespace CEGUI
00049 {
00050 
00056 template <typename Ret, typename Args>
00057 class SubscriberInterface {
00058 public:
00059   virtual Ret operator()(Args) const = 0;
00060   virtual ~SubscriberInterface() {}
00061 };
00062 
00063 
00068 template <typename Ret, typename Args>
00069 class _freeBinder : public SubscriberInterface<Ret,Args>
00070 {
00071 public:
00072   virtual Ret operator()(Args args) const 
00073   {
00074     return d_f(args);
00075   }
00076   typedef Ret (*SlotFunction)(Args);
00077   _freeBinder(SlotFunction f) : d_f(f) {}
00078 protected:
00079   SlotFunction d_f;
00080 };
00081 
00082 
00087 template <class Functor, typename Ret, typename Args>
00088 class _functorBinder : public SubscriberInterface<Ret,Args>
00089 {
00090 public:
00091   virtual Ret operator()(Args args) const 
00092   {
00093     return d_f(args);
00094   }
00095   _functorBinder(const Functor& f) : d_f(f) {}
00096 protected:
00097   Functor d_f;
00098 };
00099 
00100 
00105 template <class T, typename Ret, typename Args>
00106 class _memberBinder : public SubscriberInterface<Ret,Args>
00107 {
00108   typedef Ret (T::*F)(Args);
00109 public:
00110   virtual Ret operator()(Args args) const
00111   {
00112     return (d_t->*d_f)(args);
00113   }
00114   _memberBinder(F f, T* t) : d_f(f), d_t(t) {}
00115 protected:
00116   F  d_f;
00117   T* d_t;
00118 };
00119 
00120 
00127 template <typename Ret, typename Args>
00128 class SubscriberTemplate
00129 {
00130 public:
00131   Ret operator()(Args args) const
00132   {
00133     return (*d_si)(args);  // call the bound function
00134   }
00135 
00136   typedef Ret (*SlotFunction)(Args);
00137 
00139   SubscriberTemplate(SlotFunction f)
00140   {
00141     d_si = new _freeBinder<Ret,Args>(f);
00142   }
00143 
00145   template <class T>
00146   SubscriberTemplate(Ret (T::*f)(Args), T* target)
00147   {
00148     d_si = new _memberBinder<T,Ret,Args>(f, target);
00149   }
00150 
00152   template <typename Functor> 
00153   SubscriberTemplate(const Functor& f)
00154   {
00155     d_si = new _functorBinder<Functor,Ret,Args>(f);
00156   }
00157 
00163   SubscriberTemplate(SubscriberInterface<Ret,Args>* si) : d_si(si) {}
00164 
00166   SubscriberTemplate(const SubscriberTemplate<Ret,Args>& copy) : d_si(copy.d_si) {}
00167 
00169   bool operator<(const SubscriberTemplate<Ret,Args>& rhs) const { return d_si < rhs.d_si; }
00170 
00172   void release() const
00173   {
00174     delete d_si;
00175   }
00176 
00177 protected:
00178   SubscriberInterface<Ret,Args>* d_si;
00179 };
00180 
00181 
00188 template <class Functor, typename Ret, typename Args>
00189 class _refBinder : public SubscriberInterface<Ret,Args>
00190 {
00191 public:
00192   virtual Ret operator()(Args args) const
00193   {
00194     return d_f(args);
00195   }
00196   _refBinder(const Functor& f) : d_f(f) {}
00197 protected:
00198   const Functor& d_f;
00199 };
00200 
00205 template <class Functor>
00206 SubscriberInterface<bool, const EventArgs&>*
00207 SubscriberRef(const Functor& f)
00208 {
00209   return new _refBinder<Functor,bool,const EventArgs&>(f);
00210 }
00211 
00212 
00224 class CEGUIEXPORT Event
00225 {
00226 public:
00231         class ConnectionInterface : public Referenced {
00232         public:
00233                 virtual bool connected() { return false; }
00234                 virtual void disconnect() {}
00235         };
00236         typedef RefPtr<ConnectionInterface> Connection;
00237 
00243         class ScopedConnection {
00244         public:
00245                 ScopedConnection(Connection conn_) : conn(conn_) {}
00246                 ~ScopedConnection() { conn->disconnect(); }
00247                 Connection conn;
00248         };
00249 
00250 
00251         typedef SubscriberTemplate<bool, const EventArgs&> Subscriber;
00252         typedef int Group;
00253 
00254         /*************************************************************************
00255                 Construction and Destruction
00256         *************************************************************************/
00261         Event(const String& name);
00262 
00267         virtual ~Event(void);
00268 
00269 
00277         const String& getName(void) const       {return d_name;}
00278 
00279 
00290         Connection subscribe(Subscriber subscriber) { return subscribe(0, subscriber); }
00291 
00292 
00307         Connection subscribe(Group group, Subscriber subscriber);
00308   
00309 
00310         /*
00311         \brief
00312                 Fires the event.  All event subscribers get called in the appropriate sequence.
00313 
00314         \param args
00315                 An object derived from EventArgs to be passed to each event subscriber.
00316 
00317         \return
00318                 Nothing.
00319         */
00320         void    operator()(EventArgs& args);
00321 
00322 private:
00323         /*************************************************************************
00324                 Copy constructor and assignment are not allowed for events
00325         *************************************************************************/
00326         Event(const Event& evt) {}
00327         Event& operator=(const Event& evt)      {return *this;}
00328 
00329         /*
00330         \brief
00331                 removes the subscriber from the event.
00332 
00333         \param subscriber
00334                 A pointer to a SubscriberInterface which is to be removed from the event.
00335 
00336         \return
00337                 - true, if the subscriber was registered with the event in the specified group and it was removed.
00338                 - false, if not.
00339         */
00340         bool unsubscribe(Subscriber subscriber, Group group=0);
00341 
00342         class GroupSubscriber {
00343         public:
00344                 Group group;
00345                 Subscriber subscriber;
00346                 GroupSubscriber(Group group_, Subscriber subscriber_) 
00347                         : group(group_), subscriber(subscriber_) {}
00348         };
00349 
00350         struct ltGroupSubscriber
00351         {
00352                 bool operator()(const GroupSubscriber& gs1, const GroupSubscriber& gs2) const
00353                 {
00354                         return gs1.group <  gs2.group ||
00355                                 gs1.group == gs2.group && gs1.subscriber < gs2.subscriber;
00356                 }
00357         };
00358         typedef std::map<GroupSubscriber, Connection, ltGroupSubscriber> ConnectionOrdering;
00359 
00360 
00361         /*************************************************************************
00362                 Implementation Data
00363         *************************************************************************/
00364         const String    d_name;         
00365         ConnectionOrdering connectionOrdering;
00366         friend class ConnectionImpl;
00367 };
00368 
00369 
00370 } // End of  CEGUI namespace section
00371 
00372 #if defined(_MSC_VER)
00373 #       pragma warning(pop)
00374 #endif
00375 
00376 #endif  // end of guard _CEGUIEvent_h_

Generated on Sat Nov 26 09:34:48 2005 for Crazy Eddies GUI System by  doxygen 1.4.5