bumped version to 0.1.0
[beacon-ss.git] / src / beacon / fast_signal.hpp
blob431530c441ed6a175e20cc999de78054fa4fa142
1 /**
2 * beacon
3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
5 */
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
31 namespace beacon {
33 namespace detail {
35 template<int Arity, typename Signature>
36 struct get_fast_signal_impl;
38 #include BOOST_PP_ITERATE()
40 } //namespace detail
42 /**
43 * Fast signal is a signal that can execute the slots
44 * within an event queue of the trackables their connected
45 * with.
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>
50 class fast_signal :
51 public detail::get_fast_signal_impl<
52 (boost::function_traits<Signature>::arity),
53 Signature>::type {
55 public:
57 /**
58 * Creates a new signal with the same connections as this instance.
59 * !!! Use with caution as there is no way of controlling the
60 * individual connections of the new signal.
62 fast_signal<Signature> & copy() {
63 fast_signal<Signature> * ret = new fast_signal<Signature>;
64 detail::signal_base::slot_list_type slts = detail::signal_base::get_slots_copy();
66 for(detail::signal_base::slot_list_type::iterator it = slts.begin();
67 it != slts.end(); ++it) {
69 ret->do_connect(it->slot, *(it->queue));
72 return *ret;
76 } //namespace beacon
78 #endif //BEACON_fast_signal_H
80 #else //BOOST_PP_IS_ITERATING
82 #define n BOOST_PP_ITERATION()
84 #define FAST_SIGNAL_IMPL_N BOOST_PP_CAT(fast_signal_impl, n)
86 template<typename Signature
87 BOOST_PP_COMMA_IF(n)
88 BOOST_PP_ENUM_PARAMS(n, typename T)>
89 class FAST_SIGNAL_IMPL_N : public detail::signal_impl<typename boost::add_pointer<Signature>::type> {
90 public:
91 typedef slot_impl_base<typename boost::add_pointer<Signature>::type> slot_type;
93 /**
94 * Emits the signal.
95 * All the connected slots are invoked with given parameters.
96 * The invocation of the slot is relayed to the event queue if
97 * the slot was connected using a trackable with non-null event queue
98 * or executed directly if the trackable was null or its event queue
99 * was null.
101 void raise(BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg)) {
102 signal_base::slot_list_type slts = signal_base::get_slots_copy();
104 for(signal_base::slot_list_type::iterator it = slts.begin();
105 it != slts.end(); ++it) {
107 intrusive_ptr<connection_impl_base> con = it->connection;
109 if (con->connected()
110 #ifdef ENABLE_CONNECTION_BLOCKING
111 && !con->blocked()
112 #endif
115 slot_type * slot = reinterpret_cast<slot_type *>(it->slot.get());
117 if (it->queue != 0) {
118 enqueue<Signature>::call(*(it->queue), *slot, con->token())
119 (BOOST_PP_ENUM_PARAMS(n, arg));
120 } else {
121 invokable::token_type::lock_t lock(con->token()->guard());
123 (*slot)(BOOST_PP_ENUM_PARAMS(n, arg));
130 * Calls raise() with the provided arguments.
132 inline void operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg)) {
133 raise(BOOST_PP_ENUM_PARAMS(n, arg));
137 #define ARG_TYPE(z, x, unused) \
138 BOOST_PP_CAT(BOOST_PP_CAT( \
139 typename boost::function_traits<Signature>::arg, \
140 BOOST_PP_INC(x)), _type)
142 template<typename Signature>
143 struct get_fast_signal_impl<n, Signature> {
145 typedef FAST_SIGNAL_IMPL_N<
146 Signature
147 BOOST_PP_COMMA_IF(n)
148 BOOST_PP_ENUM(n, ARG_TYPE, ~)> type;
151 #undef n
152 #undef FAST_SIGNAL_IMPL_N
153 #undef ARG_TYPE
155 #endif //BOOST_PP_IS_ITERATING