Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/util/sigslot/slot.h @ 9361

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

more and better adaptions

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