source: GTP/trunk/App/Demos/Geom/OgreStuff/include/CEGUI/CEGUIEvent.h @ 1812

Revision 1812, 10.0 KB checked in by gumbau, 18 years ago (diff)
RevLine 
[1812]1/************************************************************************
2        filename: CEGUIEvent.h
3        created:  15/10/2004
4        authors:  Paul D Turner (High-level design)
5            Gerald Lindsly (Coder)
6       
7        purpose:  Defines interface for Event class
8*************************************************************************/
9/*************************************************************************
10    Crazy Eddie's GUI System (http://www.cegui.org.uk)
11    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
12
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2.1 of the License, or (at your option) any later version.
17
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26*************************************************************************/
27#ifndef _CEGUIEvent_h_
28#define _CEGUIEvent_h_
29
30#if defined (_MSC_VER)
31#       pragma warning(push)
32#       pragma warning(disable : 4786)
33#       pragma warning(disable : 4251)
34#       if !defined (_MSC_EXTENSIONS)
35#               pragma warning (disable : 4224)
36#       endif
37#endif
38
39#include "CEGUIBase.h"
40#include "CEGUIString.h"
41#include "CEGUIEventArgs.h"
42#include "CEGUIRefPtr.h"
43
44#include <map>
45
46
47// Start of CEGUI namespace section
48namespace CEGUI
49{
50
51/*!
52\brief
53    The base class for the various binders.  This provides a consistent
54    interface for firing functions bound to an event.
55*/
56template <typename Ret, typename Args>
57class SubscriberInterface {
58public:
59  virtual Ret operator()(Args) const = 0;
60  virtual ~SubscriberInterface() {}
61};
62
63
64/*!
65\brief
66    This class binds a free function.
67*/
68template <typename Ret, typename Args>
69class _freeBinder : public SubscriberInterface<Ret,Args>
70{
71public:
72  virtual Ret operator()(Args args) const
73  {
74    return d_f(args);
75  }
76  typedef Ret (*SlotFunction)(Args);
77  _freeBinder(SlotFunction f) : d_f(f) {}
78protected:
79  SlotFunction d_f;
80};
81
82
83/*!
84\brief
85    This class binds a copy of a functor.
86*/
87template <class Functor, typename Ret, typename Args>
88class _functorBinder : public SubscriberInterface<Ret,Args>
89{
90public:
91  virtual Ret operator()(Args args) const
92  {
93    return d_f(args);
94  }
95  _functorBinder(const Functor& f) : d_f(f) {}
96protected:
97  Functor d_f;
98};
99
100
101/*!
102\brief
103    This class binds a member function along with a target object.
104*/
105template <class T, typename Ret, typename Args>
106class _memberBinder : public SubscriberInterface<Ret,Args>
107{
108  typedef Ret (T::*F)(Args);
109public:
110  virtual Ret operator()(Args args) const
111  {
112    return (d_t->*d_f)(args);
113  }
114  _memberBinder(F f, T* t) : d_f(f), d_t(t) {}
115protected:
116  F  d_f;
117  T* d_t;
118};
119
120
121/*!
122\brief
123    This template describes the Subscriber class.  It is a wrapper
124    for a pointer to a SubscriberInterface with various constructors
125    that will by implicit conversion construct the various binders.
126*/
127template <typename Ret, typename Args>
128class SubscriberTemplate
129{
130public:
131  Ret operator()(Args args) const
132  {
133    return (*d_si)(args);  // call the bound function
134  }
135
136  typedef Ret (*SlotFunction)(Args);
137
138  //! construct from a free function
139  SubscriberTemplate(SlotFunction f)
140  {
141    d_si = new _freeBinder<Ret,Args>(f);
142  }
143
144  //! construct from a member function and a pointer to the target object.
145  template <class T>
146  SubscriberTemplate(Ret (T::*f)(Args), T* target)
147  {
148    d_si = new _memberBinder<T,Ret,Args>(f, target);
149  }
150
151  //! construct from a generalized functor by copying it
152  template <typename Functor>
153  SubscriberTemplate(const Functor& f)
154  {
155    d_si = new _functorBinder<Functor,Ret,Args>(f);
156  }
157
158  /*!
159  \brief
160    construct from a preconstructed SubscriberInterface.
161    used for SubscriberRef().
162  */
163  SubscriberTemplate(SubscriberInterface<Ret,Args>* si) : d_si(si) {}
164
165  //! copy constructor
166  SubscriberTemplate(const SubscriberTemplate<Ret,Args>& copy) : d_si(copy.d_si) {}
167
168  //! 'less than' comparable for insertion in a map
169  bool operator<(const SubscriberTemplate<Ret,Args>& rhs) const { return d_si < rhs.d_si; }
170
171  //! release the binding -- called upon disconnection
172  void release() const
173  {
174    delete d_si;
175  }
176
177protected:
178  SubscriberInterface<Ret,Args>* d_si;
179};
180
181
182/*!
183\brief
184    This class binds a const reference to a generalized functor.
185    Sometimes it may not be appropriate for the functor to be
186    cloned.  In which case, use SubscriberRef() (which uses this).
187*/
188template <class Functor, typename Ret, typename Args>
189class _refBinder : public SubscriberInterface<Ret,Args>
190{
191public:
192  virtual Ret operator()(Args args) const
193  {
194    return d_f(args);
195  }
196  _refBinder(const Functor& f) : d_f(f) {}
197protected:
198  const Functor& d_f;
199};
200
201/*!
202\brief
203    This helper function produces a const reference binding
204*/
205template <class Functor>
206SubscriberInterface<bool, const EventArgs&>*
207SubscriberRef(const Functor& f)
208{
209  return new _refBinder<Functor,bool,const EventArgs&>(f);
210}
211
212
213/*!
214\brief
215        Defines an 'event' which can be subscribed to by interested parties.
216
217        An Event can be subscribed by a function, a member function, or a function object.  Whichever option
218        is taken, the function signature needs to be as follows
219        \par
220        <em>bool function_name(const EventArgs& args);</em>
221        \note
222                An Event object may not be copied.
223*/
224class CEGUIEXPORT Event
225{
226public:
227    /*!
228    \brief
229        Interface to be implemented by connection objects.
230    */
231        class ConnectionInterface : public Referenced {
232        public:
233                virtual bool connected() { return false; }
234                virtual void disconnect() {}
235        };
236        typedef RefPtr<ConnectionInterface> Connection;
237
238    /*!
239    \brief
240        A Connection object that automatically disconnects from the event
241        when the ScropedConnection object goes out of scope (and is deleted).
242    */
243        class ScopedConnection {
244        public:
245                ScopedConnection(Connection conn_) : conn(conn_) {}
246                ~ScopedConnection() { conn->disconnect(); }
247                Connection conn;
248        };
249
250
251        typedef SubscriberTemplate<bool, const EventArgs&> Subscriber;
252        typedef int Group;
253
254        /*************************************************************************
255                Construction and Destruction
256        *************************************************************************/
257        /*!
258        \brief
259                Constructs a new Event object with the specified name
260        */
261        Event(const String& name);
262
263        /*!
264        \brief
265                Destructor for Event objects
266        */
267        virtual ~Event(void);
268
269
270        /*!
271        \brief
272                Return the name given to this Event object when it was created.
273
274        \return
275                String object containing the name of the Event object.
276        */
277        const String& getName(void) const       {return d_name;}
278
279
280        /*!
281        \brief
282                Subscribes some function / object to the Event
283
284        \param subscriber
285                A function, static member function, or function object, with the signature void function_name(const EventArgs& args)
286
287        \return
288                A Connection pointer which can be used to disconnect (unsubscribe) from the Event, and to check the connection state.
289        */
290        Connection subscribe(Subscriber subscriber) { return subscribe(0, subscriber); }
291
292
293        /*!
294        \brief
295                Subscribes some function / object to the Event
296
297        \param group
298                The Event group to subscribe to, subscription groups are called in ascending order, followed by subscriptions with no group.
299                connections to the same group may be called in any order.
300
301        \param subscriber
302                A function, static member function, or function object, with the signature void function_name(const EventArgs& args)
303
304        \return
305                A Connection which can be used to disconnect (unsubscribe) from the Event, and to check the connection state.
306        */
307        Connection subscribe(Group group, Subscriber subscriber);
308 
309
310        /*
311        \brief
312                Fires the event.  All event subscribers get called in the appropriate sequence.
313
314        \param args
315                An object derived from EventArgs to be passed to each event subscriber.
316
317        \return
318                Nothing.
319        */
320        void    operator()(EventArgs& args);
321
322private:
323        /*************************************************************************
324                Copy constructor and assignment are not allowed for events
325        *************************************************************************/
326        Event(const Event& evt) {}
327        Event& operator=(const Event& evt)      {return *this;}
328
329        /*
330        \brief
331                removes the subscriber from the event.
332
333        \param subscriber
334                A pointer to a SubscriberInterface which is to be removed from the event.
335
336        \return
337                - true, if the subscriber was registered with the event in the specified group and it was removed.
338                - false, if not.
339        */
340        bool unsubscribe(Subscriber subscriber, Group group=0);
341
342        class GroupSubscriber {
343        public:
344                Group group;
345                Subscriber subscriber;
346                GroupSubscriber(Group group_, Subscriber subscriber_)
347                        : group(group_), subscriber(subscriber_) {}
348        };
349
350        struct ltGroupSubscriber
351        {
352                bool operator()(const GroupSubscriber& gs1, const GroupSubscriber& gs2) const
353                {
354                        return gs1.group <  gs2.group ||
355                                gs1.group == gs2.group && gs1.subscriber < gs2.subscriber;
356                }
357        };
358        typedef std::map<GroupSubscriber, Connection, ltGroupSubscriber> ConnectionOrdering;
359
360
361        /*************************************************************************
362                Implementation Data
363        *************************************************************************/
364        const String    d_name;         //!< Name of this event
365        ConnectionOrdering connectionOrdering;
366        friend class ConnectionImpl;
367};
368
369
370} // End of  CEGUI namespace section
371
372#if defined(_MSC_VER)
373#       pragma warning(pop)
374#endif
375
376#endif  // end of guard _CEGUIEvent_h_
Note: See TracBrowser for help on using the repository browser.