8 #ifndef _QI_DETAILS_TRACKABLE_HXX_
9 #define _QI_DETAILS_TRACKABLE_HXX_
11 #include <boost/function.hpp>
12 #include <boost/bind.hpp>
13 #include <boost/type_traits/is_base_of.hpp>
14 #include <boost/type_traits/remove_pointer.hpp>
15 #include <boost/weak_ptr.hpp>
16 #include <boost/function_types/result_type.hpp>
22 : _wasDestroyed(false)
24 _ptr = boost::shared_ptr<T>(ptr,
boost::bind(&Trackable::_destroyed, _1));
37 boost::mutex::scoped_lock lock(_mutex);
38 while (!_wasDestroyed)
48 boost::mutex::scoped_lock lock(_mutex);
60 qiLogError(
"qi.Trackable") <<
"Trackable destroyed without calling destroy()";
75 return boost::weak_ptr<T>(_ptr);
83 template<
typename WT,
typename ST,
typename F>
87 typedef typename boost::function_types::result_type<F>::type Result;
88 LockAndCall(
const WT& arg, boost::function<F> func, boost::function<
void()> onFail)
94 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
95 QI_GEN_MAYBE_TEMPLATE_OPEN(comma) \
97 QI_GEN_MAYBE_TEMPLATE_CLOSE(comma) \
98 Result operator()(ADECL) { \
99 ST s = _wptr.lock(); \
111 boost::function<F> _f;
112 boost::function<void()> _onFail;
115 template<
typename T,
bool IS_TRACKABLE>
struct BindTransform
117 typedef const T& type;
118 static type transform(
const T& arg)
123 static boost::function<F> wrap(
const T& arg, boost::function<F> func, boost::function<
void()> onFail)
129 template<
typename T>
struct BindTransform<boost::weak_ptr<T>, false >
132 static T* transform(
const boost::weak_ptr<T>& arg)
136 return arg.lock().get();
139 static boost::function<F> wrap(
const boost::weak_ptr<T>& arg, boost::function<F> func, boost::function<
void()> onFail)
141 return LockAndCall<boost::weak_ptr<T>, boost::shared_ptr<T>, F>(arg, func, onFail);
145 template<
typename T>
struct BindTransform<T*,
true>
148 static T* transform(T*
const & arg)
154 static boost::function<F> wrap(T*
const & arg, boost::function<F> func, boost::function<
void()> onFail)
156 return LockAndCall<boost::weak_ptr<T>, boost::shared_ptr<T>, F>(arg->weakPtr(), func, onFail);
167 template<
typename RF,
typename AF>
168 boost::function<RF>
bind(
const AF& fun)
172 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
173 template<typename RF, typename AF, typename ARG0 comma ATYPEDECL> \
174 boost::function<RF> bind(const AF& fun, const ARG0& arg0 comma ADECL) \
176 typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform; \
177 typename Transform::type transformed = Transform::transform(arg0); \
178 boost::function<RF> f = boost::bind(fun, transformed comma AUSE); \
179 return Transform::wrap(arg0, f, detail::throwPointerLockException); \
181 template<typename RF, typename AF, typename ARG0 comma ATYPEDECL> \
182 boost::function<RF> bindWithFallback(const boost::function<void()> onFail, const AF& fun, const ARG0& arg0 comma ADECL) \
184 typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform; \
185 typename Transform::type transformed = Transform::transform(arg0); \
186 boost::function<RF> f = boost::bind(fun, transformed comma AUSE); \
187 return Transform::wrap(arg0, f, onFail); \
192 template<
typename F,
typename ARG0>
193 boost::function<F>
track(
const boost::function<F>& f,
const ARG0& arg0)
195 typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;
198 template<
typename F,
typename ARG0>
200 const boost::function<F>& f,
const ARG0& arg0)
202 typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;
203 return Transform::wrap(arg0, f, onFail);
207 #endif // _QI_DETAILS_TRACKABLE_HXX_
boost::weak_ptr< T > weakPtr()
void destroy()
Stop and flush the logging system.
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)
boost::shared_ptr< T > lock()
void throwPointerLockException()
#define qiLogError(...)
Log in error mode.
boost::function< F > trackWithFallback(boost::function< void()> onFail, const boost::function< F > &f, const ARG0 &arg0)
boost::function< RF > bind(const AF &fun,...)
boost::function< F > track(const boost::function< F > &f, const ARG0 &arg0)