QtGStreamer 0.10.1
|
00001 /* 00002 Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com> 00003 Copyright (C) 2010 Collabora Ltd. 00004 @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk> 00005 00006 This library is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU Lesser General Public License as published 00008 by the Free Software Foundation; either version 2.1 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 #if !defined(BOOST_PP_IS_ITERATING) || !BOOST_PP_IS_ITERATING 00020 00021 # ifndef IN_QGLIB_SIGNAL_H 00022 # error "This file must not be included directly" 00023 # endif 00024 00025 # include "value.h" 00026 # include "quark.h" 00027 # include <QtCore/QList> 00028 # include <QtCore/QDebug> 00029 # include <stdexcept> 00030 00031 00032 namespace QGlib { 00033 namespace Private { 00034 00036 QTGLIB_EXPORT Value emit(void *instance, const char *signal, Quark detail, const QList<Value> & args); 00037 00038 template <typename Signature> 00039 struct EmitImpl {}; 00040 00041 } //namespace Private 00042 } //namespace QGlib 00043 00044 00045 # if QGLIB_HAVE_CXX0X 00046 00047 namespace QGlib { 00048 namespace Private { 00049 00050 //BEGIN ******** packArguments ******** 00051 00052 inline QList<Value> packArguments() 00053 { 00054 return QList<Value>(); 00055 } 00056 00057 template <typename Arg1, typename... Args> 00058 QList<Value> packArguments(const Arg1 & a1, const Args & ... args) 00059 { 00060 QList<Value> && result = packArguments(args...); 00061 Value v; 00062 v.init<Arg1>(); 00063 ValueImpl<Arg1>::set(v, a1); 00064 //prepend, since we are packing from the last to the first argument 00065 result.prepend(v); 00066 return result; 00067 } 00068 00069 //END ******** packArguments ******** 00070 //BEGIN ******** EmitImpl ******** 00071 00072 template <typename R, typename... Args> 00073 struct EmitImpl<R (Args...)> 00074 { 00075 static inline R emit(void *instance, const char *signal, Quark detail, const Args & ... args) 00076 { 00077 try { 00078 Value && returnValue = Private::emit(instance, signal, detail, packArguments(args...)); 00079 return ValueImpl<R>::get(returnValue); 00080 } catch(const std::exception & e) { 00081 qCritical() << "Error during emission of signal" << signal << ":" << e.what(); 00082 return R(); 00083 } 00084 } 00085 }; 00086 00087 template <typename... Args> 00088 struct EmitImpl<void (Args...)> 00089 { 00090 static inline void emit(void *instance, const char *signal, Quark detail, const Args & ... args) 00091 { 00092 try { 00093 Value && returnValue = Private::emit(instance, signal, detail, packArguments(args...)); 00094 00095 if (returnValue.isValid()) { 00096 qWarning() << "Ignoring return value from emission of signal" << signal; 00097 } 00098 } catch(const std::exception & e) { 00099 qCritical() << "Error during emission of signal" << signal << ":" << e.what(); 00100 } 00101 } 00102 }; 00103 00104 //END ******** EmitImpl ******** 00105 00106 } //namespace Private 00107 00108 //BEGIN ******** QGlib::emit ******** 00109 00110 template <typename R, typename... Args> 00111 R emit(void *instance, const char *detailedSignal, const Args & ... args) 00112 { 00113 return Private::EmitImpl<R (Args...)>::emit(instance, detailedSignal, Quark(), args...); 00114 } 00115 00116 template <typename R, typename... Args> 00117 R emitWithDetail(void *instance, const char *signal, Quark detail, const Args & ... args) 00118 { 00119 return Private::EmitImpl<R (Args...)>::emit(instance, signal, detail, args...); 00120 } 00121 00122 //END ******** QGlib::emit ******** 00123 00124 } //namespace QGlib 00125 00126 # else //QGLIB_HAVE_CXX0X 00127 00128 # include <boost/preprocessor.hpp> 00129 00130 // include the second part of this file as many times as QGLIB_SIGNAL_MAX_ARGS specifies 00131 # define BOOST_PP_ITERATION_PARAMS_1 (3,(0, QGLIB_SIGNAL_MAX_ARGS, "QGlib/emitimpl.h")) 00132 # include BOOST_PP_ITERATE() 00133 # undef BOOST_PP_ITERATION_PARAMS_1 00134 00135 # endif //QGLIB_HAVE_CXX0X 00136 00137 00138 #else // !defined(BOOST_PP_IS_ITERATING) || !BOOST_PP_IS_ITERATING 00139 00140 /* 00141 This part is included from BOOST_PP_ITERATE(). It defines specializations of struct EmitImpl 00142 with different number of arguments as well as the multiple implementations of the non-variadic 00143 QGlib::emit. This part is included multiple times (QGLIB_SIGNAL_MAX_ARGS defines how many), 00144 and each time it defines those classes and functions with different number of arguments. 00145 The concept is based on the implementation of boost::function. 00146 */ 00147 00148 # define QGLIB_SIGNAL_IMPL_NUM_ARGS \ 00149 BOOST_PP_ITERATION() 00150 00151 # define QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS \ 00152 BOOST_PP_ENUM_TRAILING_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, typename A) 00153 00154 # define QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS \ 00155 BOOST_PP_ENUM_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, typename A) 00156 00157 # define QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_ARGS \ 00158 BOOST_PP_ENUM_TRAILING_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, A) 00159 00160 # define QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS \ 00161 BOOST_PP_ENUM_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, A) 00162 00163 # define QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS \ 00164 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, const A, & a) 00165 00166 # define QGLIB_SIGNAL_IMPL_FUNCTION_ARGS \ 00167 BOOST_PP_ENUM_TRAILING_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, a) 00168 00169 00170 namespace QGlib { 00171 namespace Private { 00172 00173 //BEGIN ******** boostpp EmitImpl ******** 00174 00175 # define QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP(z, n, list) \ 00176 { \ 00177 Value v; \ 00178 v.init<A##n>(); \ 00179 ValueImpl<A##n>::set(v, a##n); \ 00180 list.append(v); \ 00181 } 00182 00183 # define QGLIB_SIGNAL_IMPL_PACK_ARGS(list) \ 00184 BOOST_PP_REPEAT(QGLIB_SIGNAL_IMPL_NUM_ARGS, QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP, list) 00185 00186 template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS> 00187 struct EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)> 00188 { 00189 static inline R emit(void *instance, const char *signal, Quark detail 00190 QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS) 00191 { 00192 try { 00193 QList<Value> values; 00194 QGLIB_SIGNAL_IMPL_PACK_ARGS(values) 00195 Value returnValue = Private::emit(instance, signal, detail, values); 00196 return ValueImpl<R>::get(returnValue); 00197 } catch(const std::exception & e) { 00198 qCritical() << "Error during emission of signal" << signal << ":" << e.what(); 00199 return R(); 00200 } 00201 } 00202 }; 00203 00204 template <QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS> 00205 struct EmitImpl<void (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)> 00206 { 00207 static inline void emit(void *instance, const char *signal, Quark detail 00208 QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS) 00209 { 00210 try { 00211 QList<Value> values; 00212 QGLIB_SIGNAL_IMPL_PACK_ARGS(values) 00213 Value returnValue = Private::emit(instance, signal, detail, values); 00214 if (returnValue.isValid()) { 00215 qWarning() << "Ignoring return value from emission of signal" << signal; 00216 } 00217 } catch(const std::exception & e) { 00218 qCritical() << "Error during emission of signal" << signal << ":" << e.what(); 00219 } 00220 } 00221 }; 00222 00223 # undef QGLIB_SIGNAL_IMPL_PACK_ARGS 00224 # undef QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP 00225 00226 //END ******** boostpp EmitImpl ******** 00227 00228 } //namespace Private 00229 00230 //BEGIN ******** boostpp QGlib::emit ******** 00231 00232 template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS> 00233 R emit(void *instance, const char *detailedSignal QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS) 00234 { 00235 return Private::EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)> 00236 ::emit(instance, detailedSignal, Quark() QGLIB_SIGNAL_IMPL_FUNCTION_ARGS); 00237 } 00238 00239 template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS> 00240 R emitWithDetail(void *instance, const char *signal, Quark detail QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS) 00241 { 00242 return Private::EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)> 00243 ::emit(instance, signal, detail QGLIB_SIGNAL_IMPL_FUNCTION_ARGS); 00244 } 00245 00246 //END ******** boostpp QGlib::emit ******** 00247 00248 } //namespace QGlib 00249 00250 # undef QGLIB_SIGNAL_IMPL_FUNCTION_ARGS 00251 # undef QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS 00252 # undef QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS 00253 # undef QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_ARGS 00254 # undef QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS 00255 # undef QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS 00256 # undef QGLIB_SIGNAL_IMPL_NUM_ARGS 00257 00258 #endif // !defined(BOOST_PP_IS_ITERATING) || !BOOST_PP_IS_ITERATING