fw4spl
Proxy.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2016.
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 #include "fwServices/registry/Proxy.hpp"
8 
9 namespace fwServices
10 {
11 namespace registry
12 {
13 
14 //-----------------------------------------------------------------------------
15 
16 Proxy::sptr Proxy::s_currentProxy = Proxy::New();
17 
18 //-----------------------------------------------------------------------------
19 
21 {
22 }
23 
24 //-----------------------------------------------------------------------------
25 
27 {
28  SLM_ASSERT("There are still " << m_channels.size() << " channel(s) in the Proxy", m_channels.empty());
29 }
30 
31 //-----------------------------------------------------------------------------
32 
33 Proxy::sptr Proxy::getDefault()
34 {
35  return Proxy::s_currentProxy;
36 }
37 
38 //-----------------------------------------------------------------------------
39 
40 void Proxy::connect(ChannelKeyType channel, ::fwCom::SignalBase::sptr signal)
41 {
42  SPTR(SigSlots) sigslots;
43 
44  {
46  ChannelMapType::iterator iter = m_channels.find(channel);
47 
48  if (iter == m_channels.end())
49  {
50  sigslots = SPTR(SigSlots)(new SigSlots);
51 
52  ::fwCore::mt::UpgradeToWriteLock writeLock(lock);
53  m_channels[channel] = sigslots;
54  }
55  else
56  {
57  sigslots = iter->second;
58  }
59  }
60 
61  ::fwCore::mt::WriteLock lock(sigslots->m_mutex);
62  auto ret = sigslots->m_signals.insert(signal);
63 
64  if(ret.second)
65  {
66  // Only connect if the signal was not already in the proxy
67  for( ::fwCom::SlotBase::sptr slot : sigslots->m_slots )
68  {
69  signal->connect( slot );
70  }
71  }
72 }
73 
74 //-----------------------------------------------------------------------------
75 
76 void Proxy::connect(ChannelKeyType channel, ::fwCom::SlotBase::sptr slot)
77 {
78  SPTR(SigSlots) sigslots;
79 
80  {
82  ChannelMapType::iterator iter = m_channels.find(channel);
83 
84  if (iter == m_channels.end())
85  {
86  sigslots = SPTR(SigSlots)(new SigSlots);
87 
88  ::fwCore::mt::UpgradeToWriteLock writeLock(lock);
89  m_channels[channel] = sigslots;
90  }
91  else
92  {
93  sigslots = iter->second;
94  }
95  }
96 
97  ::fwCore::mt::WriteLock lock(sigslots->m_mutex);
98  auto ret = sigslots->m_slots.insert(slot);
99 
100  if(ret.second)
101  {
102  // Only connect if the slot was not already in the proxy
103  for( ::fwCom::SignalBase::sptr signal : sigslots->m_signals )
104  {
105  signal->connect( slot );
106  }
107  }
108 }
109 
110 //-----------------------------------------------------------------------------
111 
112 void Proxy::disconnect(ChannelKeyType channel, ::fwCom::SignalBase::sptr signal)
113 {
115  ChannelMapType::iterator iter = m_channels.find(channel);
116 
117  SLM_ASSERT("channel '" << channel << "' doesn't exist in Proxy.", iter != m_channels.end());
118  SPTR(SigSlots) sigslots = iter->second;
119 
120  ::fwCore::mt::WriteLock sigSlotLock(sigslots->m_mutex);
121 
122  for( ::fwCom::SlotBase::sptr slot : sigslots->m_slots )
123  {
124  signal->disconnect( slot );
125  }
126 
127  SigSlots::SignalContainerType::iterator sigIter;
128  sigIter = std::find(sigslots->m_signals.begin(), sigslots->m_signals.end(), signal);
129  SLM_ASSERT("Signal is not found", sigIter != sigslots->m_signals.end());
130  sigslots->m_signals.erase(sigIter);
131 
132  if (sigslots->m_signals.empty() && sigslots->m_slots.empty())
133  {
134  ::fwCore::mt::UpgradeToWriteLock writeLock(lock);
135  m_channels.erase(channel);
136  }
137 }
138 
139 //-----------------------------------------------------------------------------
140 
141 void Proxy::disconnect(ChannelKeyType channel, ::fwCom::SlotBase::sptr slot)
142 {
144  ChannelMapType::iterator iter = m_channels.find(channel);
145 
146  SLM_ASSERT("channel '" << channel << "' doesn't exist in Proxy.", iter != m_channels.end());
147  SPTR(SigSlots) sigslots = iter->second;
148 
149  ::fwCore::mt::WriteLock sigSlotLock(sigslots->m_mutex);
150 
151  for( ::fwCom::SignalBase::sptr signal : sigslots->m_signals )
152  {
153  signal->disconnect( slot );
154  }
155 
156  SigSlots::SlotContainerType::iterator slotIter;
157  slotIter = std::find(sigslots->m_slots.begin(), sigslots->m_slots.end(), slot);
158  SLM_ASSERT("Slot is not found", slotIter != sigslots->m_slots.end());
159  sigslots->m_slots.erase(slotIter);
160 
161  if (sigslots->m_signals.empty() && sigslots->m_slots.empty())
162  {
163  ::fwCore::mt::UpgradeToWriteLock writeLock(lock);
164  m_channels.erase(channel);
165  }
166 }
167 
168 //-----------------------------------------------------------------------------
169 
170 } // namespace registry
171 } // namespace fwServices
172 
#define SPTR(_cls_)
FWSERVICES_API Proxy()
Constructor, does nothing.
Definition: Proxy.cpp:20
Contains fwAtomsFilter::registry details.
::boost::upgrade_lock< ReadWriteMutex > ReadToWriteLock
Defines an upgradable lock type for read/write mutex.
::boost::upgrade_to_unique_lock< ReadWriteMutex > UpgradeToWriteLock
Defines a write lock upgraded from ReadToWriteLock.
static FWSERVICES_API Proxy::sptr getDefault()
Returns an instance of Proxy.
Definition: Proxy.cpp:33
static Proxy::sptr s_currentProxy
The global instance of the proxy.
Definition: Proxy.hpp:87
Namespace fwServices is dedicated to (mimic) the dynamic affectation of methods to (pure data) object...
ChannelMapType m_channels
Association channels, SigSlot.
Definition: Proxy.hpp:81
::boost::unique_lock< ReadWriteMutex > WriteLock
Defines a lock of write type for read/write mutex.
virtual FWSERVICES_API ~Proxy()
Destructor, does nothing.
Definition: Proxy.cpp:26
Structure to regsiter signal and slot informations Contains a signal container, a slot container and ...
Definition: Proxy.hpp:44
mutable::fwCore::mt::ReadWriteMutex m_channelMutex
Used to protect the m_channels access.
Definition: Proxy.hpp:84
FWSERVICES_API void disconnect(ChannelKeyType channel,::fwCom::SignalBase::sptr signal)
Unregisters the signal. Disconnects it from the slots in channel.
Definition: Proxy.cpp:112
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
FWSERVICES_API void connect(ChannelKeyType channel,::fwCom::SignalBase::sptr signal)
Registers a signal in the channel. It will be connected to all slots in the channel.
Definition: Proxy.cpp:40