fw4spl
WeakCall.hpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #ifndef __FWCOM_UTIL_WEAKCALL_HPP__
8 #define __FWCOM_UTIL_WEAKCALL_HPP__
9 
10 #include "fwCom/exception/WorkerChanged.hpp"
11 
12 #include <fwCore/exceptionmacros.hpp>
13 #include <fwCore/mt/types.hpp>
14 
15 #include <functional>
16 
17 namespace fwCom
18 {
19 
20 namespace util
21 {
22 
34 template< typename T, typename R >
35 struct WeakCall
36 {
37 
38  WeakCall( const std::shared_ptr< T const >& ptr, std::function< R() > f) :
39  m_weakPtr(ptr),
40  m_func(f)
41  {
42  SLM_TRACE("WeakCall object : " + ptr->getClassname() );
43  }
44 
45  WeakCall( const std::shared_ptr< T const >& ptr, std::function< R() > f,
46  const std::shared_ptr< ::fwThread::Worker >& m) :
47  m_weakPtr(ptr),
48  m_func(f),
49  m_worker( m )
50  {
51  SLM_TRACE("WeakCall object : " + ptr->getClassname() );
52  }
53 
54  ~WeakCall()
55  {
56  }
57 
58  //------------------------------------------------------------------------------
59 
60  R operator ()() const
61  {
62  std::shared_ptr< T const > ptr(this->m_weakPtr.lock());
63 
64  if (!ptr)
65  {
66  m_worker.reset();
67  // will throw an exception because m_weakPtr is expired
68  std::shared_ptr< T const > ptr(this->m_weakPtr);
69  }
70 
71  ::fwCore::mt::ReadLock lock(ptr->m_workerMutex);
72 
73  std::shared_ptr< ::fwThread::Worker > worker = m_worker.lock();
74 
75  if (worker && ptr->m_worker != worker)
76  {
77  //Worker changed since WeakCall creation
78  FW_RAISE_EXCEPTION(::fwCom::exception::WorkerChanged("Worker changed since WeakCall creation"));
79  }
80 
81  this->m_weakPtr.reset();
82 
83  return this->m_func();
84  }
85 
86  protected:
87  mutable std::weak_ptr< T const > m_weakPtr;
88  std::function< R() > m_func;
89  mutable std::weak_ptr< ::fwThread::Worker > m_worker;
90 };
91 
93 template <typename T, typename R >
94 WeakCall<T, R> weakcall( const std::shared_ptr< T const >& ptr, std::function< R() > f)
95 {
96  return WeakCall<T, R>(ptr, f);
97 }
98 
100 template <typename T, typename R >
101 WeakCall<T, R> weakcall( const std::shared_ptr< T const >& ptr, std::function< R() > f,
102  const std::shared_ptr< ::fwThread::Worker >& m)
103 {
104  return WeakCall<T, R>(ptr, f, m);
105 }
106 
107 } // namespace util
108 
109 } // namespace fwCom
110 
111 #endif /* __FWCOM_UTIL_WEAKCALL_HPP__ */
112 
Namespace containing fw4spl communication tools.
Definition: DumpEditor.hpp:30
WeakCall< T, R > weakcall(const std::shared_ptr< T const > &ptr, std::function< R() > f)
Returns weak call from given object and function.
Definition: WeakCall.hpp:94
::boost::shared_lock< ReadWriteMutex > ReadLock
Defines a lock of read type for read/write mutex.
Weak functor class. Store a zero-arg-function and a weak pointer on an object. The WeakCall is callab...
Definition: SlotBase.hpp:32
#define SLM_TRACE(message)
Definition: spyLog.hpp:228