Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/statechart/processor_container.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 12.4 KB
Line 
1#ifndef BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
2#define BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
3//////////////////////////////////////////////////////////////////////////////
4// Copyright 2002-2006 Andreas Huber Doenni
5// Distributed under the Boost Software License, Version 1.0. (See accompany-
6// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7//////////////////////////////////////////////////////////////////////////////
8
9
10
11#include <boost/statechart/event_base.hpp>
12#include <boost/statechart/event_processor.hpp>
13
14#include <boost/assert.hpp>
15#include <boost/noncopyable.hpp>
16#include <boost/intrusive_ptr.hpp>
17#include <boost/shared_ptr.hpp>
18#include <boost/weak_ptr.hpp>
19#include <boost/bind.hpp>
20#include <boost/config.hpp> // BOOST_INTEL
21
22#include <boost/detail/workaround.hpp>
23#include <boost/detail/allocator_utilities.hpp>
24
25#include <set>
26#include <memory>   // std::allocator, std::auto_ptr
27
28
29
30namespace boost
31{
32namespace statechart
33{
34
35
36
37template<
38  class Scheduler,
39  class WorkItem,
40  class Allocator = std::allocator< void > >
41class processor_container : noncopyable
42{
43  typedef event_processor< Scheduler > processor_base_type;
44  typedef std::auto_ptr< processor_base_type > processor_holder_type;
45  typedef shared_ptr< processor_holder_type > processor_holder_ptr_type;
46  public:
47    //////////////////////////////////////////////////////////////////////////
48    typedef weak_ptr< processor_holder_type > processor_handle;
49
50    class processor_context
51    {
52        processor_context(
53          Scheduler & scheduler, const processor_handle & handle
54        ) :
55          scheduler_( scheduler ),
56          handle_( handle )
57        {
58        }
59
60      #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
61      public:
62      // for some reason Intel 8.0 seems to think that the following functions
63      // are inaccessible from event_processor<>::event_processor
64      #endif
65
66        Scheduler & my_scheduler() const { return scheduler_; }
67        const processor_handle & my_handle() const { return handle_; }
68
69      #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
70      private:
71      #endif
72
73        Scheduler & scheduler_;
74        const processor_handle handle_;
75
76        friend class processor_container;
77        friend class event_processor< Scheduler >;
78    };
79
80    template< class Processor >
81    WorkItem create_processor( processor_handle & handle, Scheduler & scheduler )
82    {
83      processor_holder_ptr_type pProcessor = make_processor_holder();
84      handle = pProcessor;
85      typedef void ( processor_container::*impl_fun_ptr )(
86        const processor_holder_ptr_type &, const processor_context & );
87      impl_fun_ptr pImpl =
88        &processor_container::template create_processor_impl0< Processor >;
89      return bind(
90        pImpl, this, pProcessor, processor_context( scheduler, handle ) );
91    }
92
93    template< class Processor, typename Arg1 >
94    WorkItem create_processor(
95      processor_handle & handle, Scheduler & scheduler, Arg1 arg1 )
96    {
97      processor_holder_ptr_type pProcessor = make_processor_holder();
98      handle = pProcessor;
99      typedef void ( processor_container::*impl_fun_ptr )(
100        const processor_holder_ptr_type &, const processor_context &, Arg1 );
101      impl_fun_ptr pImpl =
102        &processor_container::template create_processor_impl1<
103          Processor, Arg1 >;
104      return bind(
105        pImpl, this, pProcessor, processor_context( scheduler, handle ), arg1 );
106    }
107
108    template< class Processor, typename Arg1, typename Arg2 >
109    WorkItem create_processor(
110      processor_handle & handle, Scheduler & scheduler, Arg1 arg1, Arg2 arg2 )
111    {
112      processor_holder_ptr_type pProcessor = make_processor_holder();
113      handle = pProcessor;
114      typedef void ( processor_container::*impl_fun_ptr )(
115        const processor_holder_ptr_type &,
116        const processor_context &, Arg1, Arg2 );
117      impl_fun_ptr pImpl =
118        &processor_container::template create_processor_impl2<
119          Processor, Arg1, Arg2 >;
120      return bind(
121        pImpl, this, pProcessor, processor_context( scheduler, handle ),
122        arg1, arg2 );
123    }
124
125    template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
126    WorkItem create_processor(
127      processor_handle & handle, Scheduler & scheduler,
128      Arg1 arg1, Arg2 arg2, Arg3 arg3 )
129    {
130      processor_holder_ptr_type pProcessor = make_processor_holder();
131      handle = pProcessor;
132      typedef void ( processor_container::*impl_fun_ptr )(
133        const processor_holder_ptr_type &,
134        const processor_context &,
135        Arg1, Arg2, Arg3 );
136      impl_fun_ptr pImpl =
137        &processor_container::template create_processor_impl3<
138          Processor, Arg1, Arg2, Arg3 >;
139      return bind(
140        pImpl, this, pProcessor, processor_context( scheduler, handle ),
141        arg1, arg2, arg3 );
142    }
143
144    template<
145      class Processor, typename Arg1, typename Arg2,
146      typename Arg3, typename Arg4 >
147    WorkItem create_processor(
148      processor_handle & handle, Scheduler & scheduler,
149      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
150    {
151      processor_holder_ptr_type pProcessor = make_processor_holder();
152      handle = pProcessor;
153      typedef void ( processor_container::*impl_fun_ptr )(
154        const processor_holder_ptr_type &,
155        const processor_context &,
156        Arg1, Arg2, Arg3, Arg4 );
157      impl_fun_ptr pImpl =
158        &processor_container::template create_processor_impl4<
159          Processor, Arg1, Arg2, Arg3, Arg4 >;
160      return bind(
161        pImpl, this, pProcessor, processor_context( scheduler, handle ),
162        arg1, arg2, arg3, arg4 );
163    }
164
165    template<
166      class Processor, typename Arg1, typename Arg2,
167      typename Arg3, typename Arg4, typename Arg5 >
168    WorkItem create_processor(
169      processor_handle & handle, Scheduler & scheduler,
170      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
171    {
172      processor_holder_ptr_type pProcessor = make_processor_holder();
173      handle = pProcessor;
174      typedef void ( processor_container::*impl_fun_ptr )(
175        const processor_holder_ptr_type &,
176        const processor_context &,
177        Arg1, Arg2, Arg3, Arg4, Arg5 );
178      impl_fun_ptr pImpl =
179        &processor_container::template create_processor_impl5<
180          Processor, Arg1, Arg2, Arg3, Arg4, Arg5 >;
181      return bind(
182        pImpl, this, pProcessor, processor_context( scheduler, handle ),
183        arg1, arg2, arg3, arg4, arg5 );
184    }
185
186    template<
187      class Processor, typename Arg1, typename Arg2,
188      typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
189    WorkItem create_processor(
190      processor_handle & handle, Scheduler & scheduler,
191      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
192    {
193      processor_holder_ptr_type pProcessor = make_processor_holder();
194      handle = pProcessor;
195      typedef void ( processor_container::*impl_fun_ptr )(
196        const processor_holder_ptr_type &,
197        const processor_context &,
198        Arg1, Arg2, Arg3, Arg4, Arg5, Arg6 );
199      impl_fun_ptr pImpl =
200        &processor_container::template create_processor_impl6<
201          Processor, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6 >;
202      return bind(
203        pImpl, this, pProcessor, processor_context( scheduler, handle ),
204        arg1, arg2, arg3, arg4, arg5, arg6 );
205    }
206
207    WorkItem destroy_processor( const processor_handle & processor )
208    {
209      return bind(
210        &processor_container::destroy_processor_impl, this, processor );
211    }
212
213    WorkItem initiate_processor( const processor_handle & processor )
214    {
215      return bind(
216        &processor_container::initiate_processor_impl, this, processor );
217    }
218
219    WorkItem terminate_processor( const processor_handle & processor )
220    {
221      return bind(
222        &processor_container::terminate_processor_impl, this, processor );
223    }
224
225    typedef intrusive_ptr< const event_base > event_ptr_type;
226
227    WorkItem queue_event(
228      const processor_handle & processor, const event_ptr_type & pEvent )
229    {
230      BOOST_ASSERT( pEvent.get() != 0 );
231
232      return bind(
233        &processor_container::queue_event_impl, this, processor, pEvent );
234    }
235
236  private:
237    //////////////////////////////////////////////////////////////////////////
238    processor_holder_ptr_type make_processor_holder()
239    {
240      return processor_holder_ptr_type( new processor_holder_type() );
241    }
242
243    template< class Processor >
244    void create_processor_impl0(
245      const processor_holder_ptr_type & pProcessor,
246      const processor_context & context )
247    {
248      processorSet_.insert( pProcessor );
249      processor_holder_type holder( new Processor( context ) );
250      *pProcessor = holder;
251    }
252
253    template< class Processor, typename Arg1 >
254    void create_processor_impl1(
255      const processor_holder_ptr_type & pProcessor,
256      const processor_context & context, Arg1 arg1 )
257    {
258      processorSet_.insert( pProcessor );
259      processor_holder_type holder( new Processor( context, arg1 ) );
260      *pProcessor = holder;
261    }
262
263    template< class Processor, typename Arg1, typename Arg2 >
264    void create_processor_impl2(
265      const processor_holder_ptr_type & pProcessor,
266      const processor_context & context, Arg1 arg1, Arg2 arg2 )
267    {
268      processorSet_.insert( pProcessor );
269      processor_holder_type holder( new Processor( context, arg1, arg2 ) );
270      *pProcessor = holder;
271    }
272
273    template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
274    void create_processor_impl3(
275      const processor_holder_ptr_type & pProcessor,
276      const processor_context & context, Arg1 arg1, Arg2 arg2, Arg3 arg3 )
277    {
278      processorSet_.insert( pProcessor );
279      processor_holder_type holder(
280        new Processor( context, arg1, arg2, arg3 ) );
281      *pProcessor = holder;
282    }
283
284    template<
285      class Processor, typename Arg1, typename Arg2,
286      typename Arg3, typename Arg4 >
287    void create_processor_impl4(
288      const processor_holder_ptr_type & pProcessor,
289      const processor_context & context,
290      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
291    {
292      processorSet_.insert( pProcessor );
293      processor_holder_type holder(
294        new Processor( context, arg1, arg2, arg3, arg4 ) );
295      *pProcessor = holder;
296    }
297
298    template<
299      class Processor, typename Arg1, typename Arg2,
300      typename Arg3, typename Arg4, typename Arg5 >
301    void create_processor_impl5(
302      const processor_holder_ptr_type & pProcessor,
303      const processor_context & context,
304      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
305    {
306      processorSet_.insert( pProcessor );
307      processor_holder_type holder(
308        new Processor( context, arg1, arg2, arg3, arg4, arg5 ) );
309      *pProcessor = holder;
310    }
311
312    template<
313      class Processor, typename Arg1, typename Arg2,
314      typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
315    void create_processor_impl6(
316      const processor_holder_ptr_type & pProcessor,
317      const processor_context & context,
318      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
319    {
320      processorSet_.insert( pProcessor );
321      processor_holder_type holder(
322        new Processor( context, arg1, arg2, arg3, arg4, arg5, arg6 ) );
323      *pProcessor = holder;
324    }
325
326    void destroy_processor_impl( const processor_handle & processor )
327    {
328      const processor_holder_ptr_type pProcessor = processor.lock();
329
330      if ( pProcessor != 0 )
331      {
332        processorSet_.erase( pProcessor );
333      }
334    }
335
336    void initiate_processor_impl( const processor_handle & processor )
337    {
338      const processor_holder_ptr_type pProcessor = processor.lock();
339
340      if ( pProcessor != 0 )
341      {
342        ( *pProcessor )->initiate();
343      }
344    }
345
346    void terminate_processor_impl( const processor_handle & processor )
347    {
348      const processor_holder_ptr_type pProcessor = processor.lock();
349
350      if ( pProcessor != 0 )
351      {
352        ( *pProcessor )->terminate();
353      }
354    }
355
356    void queue_event_impl(
357      const processor_handle & processor, const event_ptr_type & pEvent )
358    {
359      const processor_holder_ptr_type pProcessor = processor.lock();
360
361      if ( pProcessor != 0 )
362      {
363        ( *pProcessor )->process_event( *pEvent );
364      }
365    }
366
367    typedef std::set< 
368      processor_holder_ptr_type, 
369      std::less< processor_holder_ptr_type >,
370      typename boost::detail::allocator::rebind_to<
371        Allocator, processor_holder_ptr_type >::type
372    > event_processor_set_type;
373
374    event_processor_set_type processorSet_;
375};
376
377
378
379} // namespace statechart
380} // namespace boost
381
382
383
384#endif
Note: See TracBrowser for help on using the repository browser.