# 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_