3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
7 #ifndef BOOST_PP_IS_ITERATING
9 #ifndef BEACON_fast_signal_H
10 #define BEACON_fast_signal_H
12 #include <beacon/config.hpp> //for BEACON_MAX_ARGS
13 #include <beacon/connection.hpp>
14 #include <beacon/event_queue.hpp>
15 #include <beacon/detail/slot.hpp>
16 #include <beacon/trackable.hpp>
17 #include <beacon/detail/connection_impl_base.hpp>
18 #include <beacon/detail/signal_impl.hpp>
19 #include <boost/type_traits/function_traits.hpp>
20 #include <boost/type_traits/add_pointer.hpp>
22 //include preprocessor magic
23 #include <boost/preprocessor/iteration/iterate.hpp>
24 #include <boost/preprocessor/repetition.hpp>
25 #include <boost/preprocessor/punctuation/comma_if.hpp>
26 #include <boost/preprocessor/cat.hpp>
28 #define BOOST_PP_ITERATION_LIMITS (0, BEACON_MAX_ARGS)
29 #define BOOST_PP_FILENAME_1 "beacon/fast_signal.hpp" // this file
35 template<int Arity
, typename Signature
>
36 struct get_fast_signal_impl
;
38 #include BOOST_PP_ITERATE()
43 * Fast signal is a signal that can execute the slots
44 * within an event queue of the trackables their connected
46 * There is no support to retrieve or track the results
47 * of those invocations (which makes the signal execution "fast").
49 template<typename Signature
>
51 public detail::get_fast_signal_impl
<
52 (boost::function_traits
<Signature
>::arity
),
58 #endif //BEACON_fast_signal_H
60 #else //BOOST_PP_IS_ITERATING
62 #define n BOOST_PP_ITERATION()
64 #define FAST_SIGNAL_IMPL_N BOOST_PP_CAT(fast_signal_impl, n)
66 template<typename Signature
68 BOOST_PP_ENUM_PARAMS(n
, typename T
)>
69 class FAST_SIGNAL_IMPL_N
: public detail::signal_impl
<typename
boost::add_pointer
<Signature
>::type
> {
71 typedef slot_impl_base
<typename
boost::add_pointer
<Signature
>::type
> slot_type
;
75 * All the connected slots are invoked with given parameters.
76 * The invocation of the slot is relayed to the event queue if
77 * the slot was connected using a trackable with non-null event queue
78 * or executed directly if the trackable was null or its event queue
81 void emit(BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)) {
82 signal_base::slot_list_type slots
= signal_base::get_slots_copy();
84 for(signal_base::slot_list_type::iterator it
= slots
.begin();
85 it
!= slots
.end(); ++it
) {
87 intrusive_ptr
<connection_impl_base
> con
= it
->connection
;
90 #ifdef ENABLE_CONNECTION_BLOCKING
95 invokable::token_ptr token
= con
->token();
100 slot_type
* slot
= reinterpret_cast<slot_type
*>(it
->slot
);
102 if (it
->queue
!= 0) {
103 enqueue
<Signature
>::call(*(it
->queue
), *slot
, token
)
104 (BOOST_PP_ENUM_PARAMS(n
, arg
));
106 (*slot
)(BOOST_PP_ENUM_PARAMS(n
, arg
));
116 * Calls emit with the provided arguments.
118 void operator()(BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)) {
119 emit(BOOST_PP_ENUM_PARAMS(n
, arg
));
123 #define ARG_TYPE(z, x, unused) \
124 BOOST_PP_CAT(BOOST_PP_CAT( \
125 typename boost::function_traits<Signature>::arg, \
126 BOOST_PP_INC(x)), _type)
128 template<typename Signature
>
129 struct get_fast_signal_impl
<n
, Signature
> {
131 typedef FAST_SIGNAL_IMPL_N
<
134 BOOST_PP_ENUM(n
, ARG_TYPE
, ~)> type
;
138 #undef FAST_SIGNAL_IMPL_N
141 #endif //BOOST_PP_IS_ITERATING