Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cleanup/src/lib/util/sigslot/slot.h @ 10636

Last change on this file since 10636 was 9406, checked in by bensch, 18 years ago

orxonox/trunk: merged the proxy back

merged with commandsvn merge -r9346:HEAD https://svn.orxonox.net/orxonox/branches/proxy .

no conflicts

File size: 5.8 KB
Line 
1/**
2 * @file slot.h
3 * @brief Slots part of Signal Slot library from Sarah Thopson
4 * @see signal.h for more information and license.
5 */
6
7#ifndef SLOT_H__
8#define SLOT_H__
9
10#include <set>
11#include <list>
12
13
14#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS))
15#       define _SIGSLOT_SINGLE_THREADED
16#elif defined(WIN32)
17#       define _SIGSLOT_HAS_WIN32_THREADS
18#       include <windows.h>
19#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)
20#       define _SIGSLOT_HAS_POSIX_THREADS
21#       include <pthread.h>
22#else
23#       define _SIGSLOT_SINGLE_THREADED
24#endif
25
26#ifndef SIGSLOT_DEFAULT_MT_POLICY
27#       ifdef _SIGSLOT_SINGLE_THREADED
28#               define SIGSLOT_DEFAULT_MT_POLICY single_threaded
29#       else
30#               define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local
31#       endif
32#endif
33
34namespace sigslot
35{
36
37  class single_threaded
38  {
39    public:
40      single_threaded()
41      {
42        ;
43      }
44
45      virtual ~single_threaded()
46      {
47        ;
48      }
49
50      virtual void lock()
51      {
52        ;
53      }
54
55      virtual void unlock()
56      {
57        ;
58      }
59  };
60
61#ifdef _SIGSLOT_HAS_WIN32_THREADS
62  // The multi threading policies only get compiled in if they are enabled.
63  class multi_threaded_global
64  {
65    public:
66      multi_threaded_global()
67      {
68        static bool isinitialised = false;
69
70        if(!isinitialised)
71        {
72          InitializeCriticalSection(get_critsec());
73          isinitialised = true;
74        }
75      }
76
77      multi_threaded_global(const multi_threaded_global&)
78      {
79        ;
80      }
81
82      virtual ~multi_threaded_global()
83      {
84        ;
85      }
86
87      virtual void lock()
88      {
89        EnterCriticalSection(get_critsec());
90      }
91
92      virtual void unlock()
93      {
94        LeaveCriticalSection(get_critsec());
95      }
96
97    private:
98      CRITICAL_SECTION* get_critsec()
99      {
100        static CRITICAL_SECTION g_critsec;
101        return &g_critsec;
102      }
103  };
104
105  class multi_threaded_local
106  {
107    public:
108      multi_threaded_local()
109      {
110        InitializeCriticalSection(&m_critsec);
111      }
112
113      multi_threaded_local(const multi_threaded_local&)
114      {
115        InitializeCriticalSection(&m_critsec);
116      }
117
118      virtual ~multi_threaded_local()
119      {
120        DeleteCriticalSection(&m_critsec);
121      }
122
123      virtual void lock()
124      {
125        EnterCriticalSection(&m_critsec);
126      }
127
128      virtual void unlock()
129      {
130        LeaveCriticalSection(&m_critsec);
131      }
132
133    private:
134      CRITICAL_SECTION m_critsec;
135  };
136#endif // _SIGSLOT_HAS_WIN32_THREADS
137
138#ifdef _SIGSLOT_HAS_POSIX_THREADS
139  // The multi threading policies only get compiled in if they are enabled.
140  class multi_threaded_global
141  {
142    public:
143      multi_threaded_global()
144      {
145        pthread_mutex_init(get_mutex(), NULL);
146      }
147
148      multi_threaded_global(const multi_threaded_global&)
149      {
150        ;
151      }
152
153      virtual ~multi_threaded_global()
154      {
155        ;
156      }
157
158      virtual void lock()
159      {
160        pthread_mutex_lock(get_mutex());
161      }
162
163      virtual void unlock()
164      {
165        pthread_mutex_unlock(get_mutex());
166      }
167
168    private:
169      pthread_mutex_t* get_mutex()
170      {
171        static pthread_mutex_t g_mutex;
172        return &g_mutex;
173      }
174  };
175
176  class multi_threaded_local
177  {
178    public:
179      multi_threaded_local()
180      {
181        pthread_mutex_init(&m_mutex, NULL);
182      }
183
184      multi_threaded_local(const multi_threaded_local&)
185      {
186        pthread_mutex_init(&m_mutex, NULL);
187      }
188
189      virtual ~multi_threaded_local()
190      {
191        pthread_mutex_destroy(&m_mutex);
192      }
193
194      virtual void lock()
195      {
196        pthread_mutex_lock(&m_mutex);
197      }
198
199      virtual void unlock()
200      {
201        pthread_mutex_unlock(&m_mutex);
202      }
203
204    private:
205      pthread_mutex_t m_mutex;
206  };
207#endif // _SIGSLOT_HAS_POSIX_THREADS
208
209  template<class mt_policy>
210  class lock_block
211  {
212    public:
213      mt_policy *m_mutex;
214
215      lock_block(mt_policy *mtx)
216          : m_mutex(mtx)
217      {
218        m_mutex->lock();
219      }
220
221      ~lock_block()
222      {
223        m_mutex->unlock();
224      }
225  };
226
227
228
229
230  template<class mt_policy>
231  class has_slots;
232
233
234  template<class mt_policy>
235  class _signal_base : public mt_policy
236  {
237    public:
238      virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
239      virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
240  };
241
242  template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
243  class has_slots //: public mt_policy
244  {
245    private:
246      typedef std::set<_signal_base<mt_policy> *> sender_set;
247      typedef typename sender_set::const_iterator const_iterator;
248
249    public:
250      has_slots()
251      {
252        ;
253      }
254
255      has_slots(const has_slots& hs)
256//          : mt_policy(hs)
257      {
258        //lock_block<mt_policy> lock(this);
259        const_iterator it = hs.m_senders.begin();
260        const_iterator itEnd = hs.m_senders.end();
261
262        while(it != itEnd)
263        {
264          (*it)->slot_duplicate(&hs, this);
265          m_senders.insert(*it);
266          ++it;
267        }
268      }
269
270      void signal_connect(_signal_base<mt_policy>* sender)
271      {
272        //lock_block<mt_policy> lock(this);
273        m_senders.insert(sender);
274      }
275
276      void signal_disconnect(_signal_base<mt_policy>* sender)
277      {
278        //lock_block<mt_policy> lock(this);
279        m_senders.erase(sender);
280      }
281
282      virtual ~has_slots()
283      {
284        disconnect_all();
285      }
286
287      void disconnect_all()
288      {
289        //lock_block<mt_policy> lock(this);
290        const_iterator it = m_senders.begin();
291        const_iterator itEnd = m_senders.end();
292
293        while(it != itEnd)
294        {
295          (*it)->slot_disconnect(this);
296          ++it;
297        }
298
299        m_senders.erase(m_senders.begin(), m_senders.end());
300      }
301
302    private:
303      sender_set m_senders;
304  };
305}
306
307#endif /* SLOT_H__ */
Note: See TracBrowser for help on using the repository browser.