Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

CEGUIEvent.h

Go to the documentation of this file.
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 
00051 /* The base class for the various binders.  This provides
00052    a consistent interface for firing functions bound to an event.
00053 */
00054 template <typename Ret, typename Args>
00055 class SubscriberInterface {
00056 public:
00057   virtual Ret operator()(Args) const = 0;
00058   virtual ~SubscriberInterface() {}
00059 };
00060 
00061 
00062 /* This class binds a free function. */
00063 template <typename Ret, typename Args>
00064 class _freeBinder : public SubscriberInterface<Ret,Args>
00065 {
00066 public:
00067   virtual Ret operator()(Args args) const 
00068   {
00069     return d_f(args);
00070   }
00071   typedef Ret (*SlotFunction)(Args);
00072   _freeBinder(SlotFunction f) : d_f(f) {}
00073 protected:
00074   SlotFunction d_f;
00075 };
00076 
00077 
00078 /* This class binds a copy of a functor. */
00079 template <class Functor, typename Ret, typename Args>
00080 class _functorBinder : public SubscriberInterface<Ret,Args>
00081 {
00082 public:
00083   virtual Ret operator()(Args args) const 
00084   {
00085     return d_f(args);
00086   }
00087   _functorBinder(const Functor& f) : d_f(f) {}
00088 protected:
00089   Functor d_f;
00090 };
00091 
00092 
00093 /* This class binds a member function along with a target
00094    object. */
00095 template <class T, typename Ret, typename Args>
00096 class _memberBinder : public SubscriberInterface<Ret,Args>
00097 {
00098   typedef Ret (T::*F)(Args);
00099 public:
00100   virtual Ret operator()(Args args) const
00101   {
00102     return (d_t->*d_f)(args);
00103   }
00104   _memberBinder(F f, T* t) : d_f(f), d_t(t) {}
00105 protected:
00106   F  d_f;
00107   T* d_t;
00108 };
00109 
00110 
00111 /* This template describes the Subscriber class.  It is a wrapper
00112    for a pointer to a SubscriberInterface with various constructors
00113    that will by implicit conversion construct the various binders. */
00114 template <typename Ret, typename Args>
00115 class SubscriberTemplate
00116 {
00117 public:
00118   Ret operator()(Args args) const
00119   {
00120     return (*d_si)(args);  // call the bound function
00121   }
00122 
00123   typedef Ret (*SlotFunction)(Args);
00124 
00125   // construct from a free function
00126   SubscriberTemplate(SlotFunction f)
00127   {
00128     d_si = new _freeBinder<Ret,Args>(f);
00129   }
00130 
00131   // construct from a member function and a pointer to the target object.
00132   template <class T>
00133   SubscriberTemplate(Ret (T::*f)(Args), T* target)
00134   {
00135     d_si = new _memberBinder<T,Ret,Args>(f, target);
00136   }
00137 
00138   // construct from a generalized functor by copying it
00139   template <typename Functor> 
00140   SubscriberTemplate(const Functor& f)
00141   {
00142     d_si = new _functorBinder<Functor,Ret,Args>(f);
00143   }
00144 
00145   /* construct from a preconstructed SubscriberInterface.
00146      used for SubscriberRef(). */
00147   SubscriberTemplate(SubscriberInterface<Ret,Args>* si) : d_si(si) {}
00148 
00149   // copy constructor
00150   SubscriberTemplate(const SubscriberTemplate<Ret,Args>& copy) : d_si(copy.d_si) {}
00151 
00152   // 'less than' comparable for insertion in a map
00153   bool operator<(const SubscriberTemplate<Ret,Args>& rhs) const { return d_si < rhs.d_si; }
00154 
00155   // release the binding -- called upon disconnection
00156   void release() const
00157   {
00158     delete d_si;
00159   }
00160 
00161 protected:
00162   SubscriberInterface<Ret,Args>* d_si;
00163 };
00164 
00165 
00166 /* This class binds a const reference to a generalized functor.
00167    Sometimes it may not be appropriate for the functor to be
00168    cloned.  In which case, use SubscriberRef() (which uses this). */
00169 template <class Functor, typename Ret, typename Args>
00170 class _refBinder : public SubscriberInterface<Ret,Args>
00171 {
00172 public:
00173   virtual Ret operator()(Args args) const
00174   {
00175     return d_f(args);
00176   }
00177   _refBinder(const Functor& f) : d_f(f) {}
00178 protected:
00179   const Functor& d_f;
00180 };
00181 
00182 /* This helper function produces a const reference binding */
00183 template <class Functor>
00184 SubscriberInterface<bool, const EventArgs&>*
00185 SubscriberRef(const Functor& f)
00186 {
00187   return new _refBinder<Functor,bool,const EventArgs&>(f);
00188 }
00189 
00190 
00202 class CEGUIBASE_API Event
00203 {
00204 public:
00205         class ConnectionInterface : public Referenced {
00206         public:
00207                 virtual bool connected() { return false; }
00208                 virtual void disconnect() {}
00209         };
00210         typedef RefPtr<ConnectionInterface> Connection;
00211 
00212 
00213         class ScopedConnection {
00214         public:
00215                 ScopedConnection(Connection conn_) : conn(conn_) {}
00216                 ~ScopedConnection() { conn->disconnect(); }
00217                 Connection conn;
00218         };
00219 
00220 
00221         typedef SubscriberTemplate<bool, const EventArgs&> Subscriber;
00222         typedef int Group;
00223 
00224         /*************************************************************************
00225                 Construction and Destruction
00226         *************************************************************************/
00231         Event(const String& name);
00232 
00237         virtual ~Event(void);
00238 
00239 
00247         const String& getName(void) const       {return d_name;}
00248 
00249 
00260         Connection subscribe(Subscriber subscriber) { return subscribe(0, subscriber); }
00261 
00262 
00277         Connection subscribe(Group group, Subscriber subscriber);
00278   
00279 
00280         /*
00281         \brief
00282                 Fires the event.  All event subscribers get called in the appropriate sequence.
00283 
00284         \param args
00285                 An object derived from EventArgs to be passed to each event subscriber.
00286 
00287         \return
00288                 Nothing.
00289         */
00290         void    operator()(EventArgs& args);
00291 
00292 private:
00293         /*************************************************************************
00294                 Copy constructor and assignment are not allowed for events
00295         *************************************************************************/
00296         Event(const Event& evt) {}
00297         Event& operator=(const Event& evt)      {return *this;}
00298 
00299         /*
00300         \brief
00301                 removes the subscriber from the event.
00302 
00303         \param subscriber
00304                 A pointer to a SubscriberInterface which is to be removed from the event.
00305 
00306         \return
00307                 - true, if the subscriber was registered with the event in the specified group and it was removed.
00308                 - false, if not.
00309         */
00310         bool unsubscribe(Subscriber subscriber, Group group=0);
00311 
00312         class GroupSubscriber {
00313         public:
00314                 Group group;
00315                 Subscriber subscriber;
00316                 GroupSubscriber(Group group_, Subscriber subscriber_) 
00317                         : group(group_), subscriber(subscriber_) {}
00318         };
00319 
00320         struct ltGroupSubscriber
00321         {
00322                 bool operator()(const GroupSubscriber& gs1, const GroupSubscriber& gs2) const
00323                 {
00324                         return gs1.group <  gs2.group ||
00325                                 gs1.group == gs2.group && gs1.subscriber < gs2.subscriber;
00326                 }
00327         };
00328         typedef std::map<GroupSubscriber, Connection, ltGroupSubscriber> ConnectionOrdering;
00329 
00330 
00331         /*************************************************************************
00332                 Implementation Data
00333         *************************************************************************/
00334         const String    d_name;         
00335         ConnectionOrdering connectionOrdering;
00336         friend class ConnectionImpl;
00337 };
00338 
00339 
00340 } // End of  CEGUI namespace section
00341 
00342 #if defined(_MSC_VER)
00343 #       pragma warning(pop)
00344 #endif
00345 
00346 #endif  // end of guard _CEGUIEvent_h_

Generated on Wed Feb 16 12:41:06 2005 for Crazy Eddies GUI System by  doxygen 1.3.9.1