fw4spl
ObjectService.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
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/ObjectService.hpp"
8 
9 #include "fwServices/IService.hpp"
10 #include "fwServices/registry/AppConfig.hpp"
11 #include "fwServices/registry/ServiceConfig.hpp"
12 #include "fwServices/registry/ServiceFactory.hpp"
13 
14 #include <fwCore/LogicStamp.hpp>
15 #include <fwCore/util/LazyInstantiator.hpp>
16 
17 #include <fwTools/fwID.hpp>
18 
19 #include <boost/filesystem.hpp>
20 
21 #include <iostream>
22 #include <sstream>
23 #include <utility>
24 
25 namespace fwServices
26 {
27 
28 //------------------------------------------------------------------------------
29 
30 namespace OSR
31 {
32 
33 //------------------------------------------------------------------------------
34 
35 ::fwServices::registry::ObjectService::sptr get()
36 {
37  return ::fwCore::util::LazyInstantiator< ::fwServices::registry::ObjectService >::getInstance();
38 }
39 
40 //------------------------------------------------------------------------------
41 
42 ::fwServices::registry::ObjectService::ObjectVectorType getObjects()
43 {
44  return ::fwServices::OSR::get()->getObjects();
45 }
46 
47 //------------------------------------------------------------------------------
48 
50 {
51  return ::fwServices::OSR::get()->getRegistryInformation();
52 }
53 
54 //------------------------------------------------------------------------------
55 
56 ::fwServices::registry::ObjectService::ServiceVectorType getServices( const std::string& serviceType )
57 {
58  return ::fwServices::OSR::get()->getServices(serviceType);
59 }
60 
61 //------------------------------------------------------------------------------
62 
63 ::fwServices::registry::ObjectService::ServiceVectorType getServices( ::fwData::Object::sptr obj,
64  const std::string& serviceType )
65 {
66  return ::fwServices::OSR::get()->getServices(obj, serviceType);
67 }
68 
69 //------------------------------------------------------------------------------
70 
71 ::fwServices::registry::ObjectService::ServiceVectorType getServices( ::fwData::Object::sptr obj )
72 {
73  return ::fwServices::OSR::get()->getServices(obj);
74 }
75 
76 //------------------------------------------------------------------------------
77 
78 bool has( ::fwData::Object::sptr obj, const std::string& srvType)
79 {
80  return ::fwServices::OSR::get()->has(obj, srvType);
81 }
82 
83 //------------------------------------------------------------------------------
84 
85 void registerService( ::fwServices::IService::sptr service )
86 {
87  ::fwServices::OSR::get()->registerService(service);
88 }
89 
90 //------------------------------------------------------------------------------
91 
92 void registerService( ::fwData::Object::sptr obj, ::fwServices::IService::sptr service )
93 {
94  ::fwServices::OSR::get()->registerService(obj, service);
95 }
96 
97 //------------------------------------------------------------------------------
98 
99 void registerService( ::fwData::Object::sptr obj, const ::fwServices::IService::KeyType& objKey,
100  ::fwServices::IService::AccessType access, ::fwServices::IService::sptr service )
101 {
102  ::fwServices::OSR::get()->registerService(obj, objKey, access, service);
103 }
104 
105 //------------------------------------------------------------------------------
106 
107 void registerServiceInput( ::fwData::Object::csptr obj, const ::fwServices::IService::KeyType& objKey,
108  ::fwServices::IService::sptr service )
109 {
110  ::fwServices::OSR::get()->registerServiceInput(obj, objKey, service);
111 }
112 
113 //------------------------------------------------------------------------------
114 
115 void registerServiceOutput( ::fwData::Object::sptr obj, const ::fwServices::IService::KeyType& objKey,
116  ::fwServices::IService::sptr service )
117 {
118  ::fwServices::OSR::get()->registerServiceOutput(obj, objKey, service);
119 }
120 
121 //------------------------------------------------------------------------------
122 
123 void swapService( ::fwData::Object::sptr objDst, ::fwServices::IService::sptr service )
124 {
125  ::fwServices::OSR::get()->swapService(objDst, service);
126 }
127 
128 //------------------------------------------------------------------------------
129 
130 void unregisterService( ::fwServices::IService::sptr service )
131 {
132  ::fwServices::OSR::get()->unregisterService(service);
133 }
134 
135 //------------------------------------------------------------------------------
136 
137 void unregisterService(const ::fwServices::IService::KeyType& objKey, ::fwServices::IService::AccessType access,
138  IService::sptr service)
139 {
140  ::fwServices::OSR::get()->unregisterService(objKey, access, service);
141 }
142 
143 //------------------------------------------------------------------------------
144 
145 void unregisterServiceOutput(const ::fwServices::IService::KeyType& objKey, IService::sptr service)
146 {
147  ::fwServices::OSR::get()->unregisterServiceOutput(objKey, service);
148 }
149 
150 //------------------------------------------------------------------------------
151 
152 bool isRegistered(const ::fwServices::IService::KeyType& objKey,
153  ::fwServices::IService::AccessType access, IService::sptr service)
154 {
155  return ::fwServices::OSR::get()->isRegistered(objKey, access, service);
156 }
157 
158 //------------------------------------------------------------------------------
159 
160 ::fwData::Object::csptr getRegistered(const ::fwServices::IService::KeyType& objKey,
161  ::fwServices::IService::AccessType access, IService::sptr service)
162 {
163  return ::fwServices::OSR::get()->getRegistered(objKey, access, service);
164 }
165 
166 //------------------------------------------------------------------------------
167 
168 } //namespace OSR
169 
170 //------------------------------------------------------------------------------
171 //------------------------------------------------------------------------------
172 
173 namespace registry
174 {
175 
176 const ::fwCom::Signals::SignalKeyType ObjectService::s_REGISTERED_SIG = "registered";
177 const ::fwCom::Signals::SignalKeyType ObjectService::s_UNREGISTERED_SIG = "unregistered";
178 
179 //------------------------------------------------------------------------------
180 
181 ObjectService::ObjectService()
182 {
183  newSignal<RegisterSignalType>(s_REGISTERED_SIG);
184  newSignal<RegisterSignalType>(s_UNREGISTERED_SIG);
185 }
186 
187 //------------------------------------------------------------------------------
188 
189 std::string ObjectService::getRegistryInformation() const
190 {
191  std::stringstream info;
192  ::fwData::Object::csptr previousObj;
193  ::fwCore::mt::ReadLock lock(m_containerMutex);
194  for( const ServiceContainerType::left_map::value_type& objSrvMap : m_container.left)
195  {
196  ::fwData::Object::csptr obj = objSrvMap.first.lock();
197 
198  if ( obj && previousObj != obj )
199  {
200  info << "Object ( id = "<<obj->getID()<<" ) has "
201  << m_container.left.count(obj) <<" services." << std::endl;
202  previousObj = obj;
203  }
204  ::fwServices::IService::sptr service = objSrvMap.second;
205  info << " srv : uid = "<< service->getID() <<" , classname = "<< service->getClassname()
206  <<" , service is stopped = "<< ( service->isStopped() ? "yes" : "no" ) << std::endl;
207  }
208  return info.str();
209 }
210 
211 //------------------------------------------------------------------------------
212 
213 void ObjectService::registerService( ::fwServices::IService::sptr service )
214 {
215  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
216  m_container.insert( ServiceContainerType::value_type( ::fwData::Object::wptr(), service ) );
217 }
218 
219 //------------------------------------------------------------------------------
220 
221 void ObjectService::registerService( ::fwData::Object::sptr object, ::fwServices::IService::sptr service )
222 {
223  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
224  FW_DEPRECATED_MSG("'ObjectService::registerSerice(object, service)' is deprecated. Use "
225  "'ObjectService::registerService(object, key, INOUT, service)' or "
226  "service->registerInOut(object, key)'.", "20.0");
227  this->internalRegisterService(object, service, "", ::fwServices::IService::AccessType::INOUT);
228 }
229 
230 //------------------------------------------------------------------------------
231 
232 void ObjectService::registerService( ::fwData::Object::sptr object, const ::fwServices::IService::KeyType& objKey,
233  ::fwServices::IService::AccessType access, ::fwServices::IService::sptr service)
234 {
235  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
236  this->internalRegisterService(object, service, objKey, access);
237 }
238 
239 //------------------------------------------------------------------------------
240 
241 void ObjectService::registerServiceInput( const ::fwData::Object::csptr& object,
242  const ::fwServices::IService::KeyType& objKey,
243  const ::fwServices::IService::sptr& service)
244 {
245  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
246  this->internalRegisterServiceInput(object, service, objKey);
247 }
248 
249 //------------------------------------------------------------------------------
250 
251 void ObjectService::registerServiceOutput(::fwData::Object::sptr object, const ::fwServices::IService::KeyType& objKey,
252  ::fwServices::IService::sptr service)
253 {
254 
255  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
256  this->internalRegisterService(object, service, objKey, ::fwServices::IService::AccessType::OUTPUT);
257 
258  const bool hasID = service->hasObjectId(objKey);
259  OSLM_DEBUG_IF("No output is defined for '" + objKey + "', the object is not emitted to the configuration", !hasID);
260  if (hasID)
261  {
262  const auto id = service->getObjectId(objKey);
263  auto sig = this->signal<RegisterSignalType>(s_REGISTERED_SIG);
264  sig->asyncEmit(object, id);
265  }
266 }
267 
268 //------------------------------------------------------------------------------
269 
270 void ObjectService::swapService( ::fwData::Object::sptr objDst, ::fwServices::IService::sptr service )
271 {
272  FW_DEPRECATED_MSG("'ObjectService::swapService(object, service)' is deprecated. Use "
273  "'service->swapKey(key, object)'.", "20.0");
274  ::fwCore::mt::WriteLock lock(m_containerMutex);
275  OSLM_ASSERT("Object "<< service->getObject()->getID()<<" is not registered in OSR",
276  m_container.left.find(service->getObject()) != m_container.left.end());
277 
278  OSLM_ASSERT("Service "<< service->getID()<<" is not registered in OSR",
279  m_container.right.find(service) != m_container.right.end());
280 
281  // TODO: swap pour chaque objet !
282  m_container.right.erase(service);
283  this->internalRegisterService(objDst, service, "", ::fwServices::IService::AccessType::INOUT);
284 }
285 
286 //------------------------------------------------------------------------------
287 
288 void ObjectService::unregisterService( ::fwServices::IService::sptr service )
289 {
290  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
291 
292  SLM_ASSERT( "The service ( " + service->getID() + " ) must be stopped before being unregistered.",
293  service->isStopped() );
294 
295  this->removeFromContainer( service );
296  service->m_inputsMap.clear();
297  service->m_inOutsMap.clear();
298  service->m_outputsMap.clear();
299 }
300 
301 //------------------------------------------------------------------------------
302 
303 void ObjectService::unregisterService(const ::fwServices::IService::KeyType& objKey,
304  ::fwServices::IService::AccessType access,
305  ::fwServices::IService::sptr service )
306 {
307  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
308 
309  ::fwData::Object::cwptr obj;
310 
311  if(access == ::fwServices::IService::AccessType::INPUT)
312  {
313  obj = service->m_inputsMap[objKey];
314  }
315  else if(access == ::fwServices::IService::AccessType::INOUT)
316  {
317  obj = service->m_inOutsMap[objKey];
318  }
319  else
320  {
321  obj = service->m_outputsMap[objKey];
322  }
323 
324  SLM_ASSERT("Object key '" + objKey + "' not found in service '" + service->getID() + "'", !obj.expired());
325 
326  // Remove from the left part
327  {
328  auto range = m_container.left.equal_range(obj);
329  for(auto it = range.first; it != range.second; )
330  {
331  if(it->second == service)
332  {
333  it = m_container.left.erase(it);
334  }
335  else
336  {
337  ++it;
338  }
339  }
340  }
341 
342  // Remove from the right part
343  {
344  auto range = m_container.right.equal_range(service);
345  for(auto it = range.first; it != range.second; )
346  {
347  if(it->second.lock() == obj.lock())
348  {
349  it = m_container.right.erase(it);
350  }
351  else
352  {
353  ++it;
354  }
355  }
356  }
357 
358  if(access == ::fwServices::IService::AccessType::INPUT)
359  {
360  service->m_inputsMap.erase(objKey);
361  }
362  else if(access == ::fwServices::IService::AccessType::INOUT)
363  {
364  service->m_inOutsMap.erase(objKey);
365  }
366  else
367  {
368  service->m_outputsMap.erase(objKey);
369  }
370 }
371 
372 //------------------------------------------------------------------------------
373 
374 void ObjectService::unregisterServiceOutput( const ::fwServices::IService::KeyType& objKey,
375  ::fwServices::IService::sptr service )
376 {
377  ::fwData::Object::wptr obj = service->m_outputsMap[objKey];
378 
379  if (service->hasObjectId(objKey))
380  {
381  const auto id = service->getObjectId(objKey);
382  auto sig = this->signal<RegisterSignalType>(s_UNREGISTERED_SIG);
383  sig->asyncEmit(obj.lock(), id);
384  }
385  service->m_outputsMap.erase(objKey);
386 }
387 
388 //------------------------------------------------------------------------------
389 
390 bool ObjectService::isRegistered(const ::fwServices::IService::KeyType& objKey,
391  ::fwServices::IService::AccessType access, IService::sptr service) const
392 {
393  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
394 
395  if(access == ::fwServices::IService::AccessType::INPUT)
396  {
397  return service->m_inputsMap.find(objKey) != service->m_inputsMap.end();
398  }
399  else if(access == ::fwServices::IService::AccessType::INOUT)
400  {
401  return service->m_inOutsMap.find(objKey) != service->m_inOutsMap.end();
402  }
403  else
404  {
405  return service->m_outputsMap.find(objKey) != service->m_outputsMap.end();
406  }
407 }
408 
409 //------------------------------------------------------------------------------
410 
411 ::fwData::Object::csptr ObjectService::getRegistered(const ::fwServices::IService::KeyType& objKey,
412  ::fwServices::IService::AccessType access,
413  IService::sptr service) const
414 {
415  ::fwCore::mt::WriteLock writeLock(m_containerMutex);
416 
417  if(access == ::fwServices::IService::AccessType::INPUT)
418  {
419  auto it = service->m_inputsMap.find(objKey);
420  if(it != service->m_inputsMap.end())
421  {
422  return it->second.lock();
423  }
424  }
425  else if(access == ::fwServices::IService::AccessType::INOUT)
426  {
427  auto it = service->m_inOutsMap.find(objKey);
428  if(it != service->m_inOutsMap.end())
429  {
430  return it->second.lock();
431  }
432  }
433  else
434  {
435  auto it = service->m_outputsMap.find(objKey);
436  if(it != service->m_outputsMap.end())
437  {
438  return it->second;
439  }
440  }
441  return nullptr;
442 }
443 
444 //------------------------------------------------------------------------------
445 
446 void ObjectService::internalRegisterService(::fwData::Object::sptr object, ::fwServices::IService::sptr service,
447  const ::fwServices::IService::KeyType& objKey,
448  ::fwServices::IService::AccessType access)
449 {
450  SLM_ASSERT("Can't register a null service in OSR.", service);
451  SLM_ASSERT("Can't register a null object in OSR.", object);
452 
453  if(objKey.empty())
454  {
455  OSLM_ASSERT("Service "<< service->getID()<<" has already a valid associated object",
456  service->m_associatedObject.expired() || object != service->m_associatedObject.lock());
457 
458  // Old behavior with 1 object -> N Services
459  OSLM_ASSERT("This service "<< service->getClassname()
460  << " is not valid for the object " << object->getClassname(),
461  ServiceFactory::getDefault()->checkServiceValidity(object->getClassname(), service->getClassname())
462  );
463 
464  OSLM_ASSERT("Service "<< service->getID()<<" already registered",
465  m_container.right.find(service) == m_container.right.end());
466 
467  service->m_associatedObject = object;
468  }
469  else
470  {
471  if(service->m_inputsMap.empty() && service->m_inOutsMap.empty() && service->m_outputsMap.empty())
472  {
473  // If we have an appXml but with an old service implementation,
474  // we consider that the primary object is the first one we added
475  service->m_associatedObject = object;
476  }
477  // new behavior with N objects -> N Services
478  if(access == ::fwServices::IService::AccessType::INPUT)
479  {
480  service->m_inputsMap[objKey] = object;
481  }
482  else if(access == ::fwServices::IService::AccessType::INOUT)
483  {
484  service->m_inOutsMap[objKey] = object;
485  }
486  else
487  {
488  service->m_outputsMap[objKey] = object;
489  }
490  }
491  m_container.insert( ServiceContainerType::value_type( object, service ) );
492 }
493 
494 //------------------------------------------------------------------------------
495 
496 void ObjectService::internalRegisterServiceInput(const fwData::Object::csptr& object, const IService::sptr& service,
497  const ::fwServices::IService::KeyType& objKey)
498 {
499  SLM_ASSERT("Can't register a null service in OSR.", service);
500  SLM_ASSERT("Can't register a null object in OSR.", object);
501  SLM_ASSERT("Can't register an input object without key.", !objKey.empty());
502 
503  service->m_inputsMap[objKey] = object;
504 
505  m_container.insert( ServiceContainerType::value_type( object, service ) );
506 }
507 
508 //------------------------------------------------------------------------------
509 
510 void ObjectService::removeFromContainer( ::fwServices::IService::sptr service )
511 {
512  SLM_TRACE_FUNC();
513  OSLM_ASSERT("Unknown service "<<service->getID()<<" in OSR",
514  m_container.right.find(service) != m_container.right.end());
515  m_container.right.erase(service);
516 }
517 
518 //------------------------------------------------------------------------------
519 
520 ObjectService::ObjectVectorType ObjectService::getObjects() const
521 {
522  ObjectVectorType objects;
523  ::fwCore::mt::ReadLock lock(m_containerMutex);
524 
525  for( const ServiceContainerType::right_map::value_type& elt : m_container.right)
526  {
527  auto srvObjects = elt.first->getObjects();
528  std::move(srvObjects.begin(), srvObjects.end(), std::inserter(objects, objects.begin()));
529  }
530  SLM_WARN_IF( "No object registered for the requested type of service", objects.empty() );
531  return objects;
532 }
533 
534 //------------------------------------------------------------------------------
535 
536 ObjectService::ServiceVectorType ObjectService::getServices( ::fwData::Object::sptr obj,
537  const std::string& serviceType ) const
538 {
539  FW_DEPRECATED_MSG("'ObjectService::getServices(object, srvType)' is deprecated.", "20.0");
540 
541  ServiceVectorType allServices = this->getServices(obj);
542  ServiceVectorType services;
543 
544  // Search should be optimized
545  for(::fwServices::IService::sptr srv : allServices)
546  {
547  if( srv->isA(serviceType) )
548  {
549  services.insert( srv );
550  }
551  }
552  return services;
553 }
554 
555 //------------------------------------------------------------------------------
556 
557 ObjectService::ServiceVectorType ObjectService::getServices( const std::string& serviceType ) const
558 {
559  ServiceVectorType services;
560  ::fwCore::mt::ReadLock lock(m_containerMutex);
561  const ServiceContainerType::right_map right = m_container.right;
562  for( ServiceContainerType::right_map::value_type elt : right)
563  {
564  ::fwServices::IService::sptr service = elt.first;
565  if ( service->isA(serviceType) )
566  {
567  services.insert( service );
568  }
569  }
570  SLM_DEBUG_IF("No service registered", services.empty());
571  return services;
572 }
573 
574 //------------------------------------------------------------------------------
575 
576 ObjectService::ServiceVectorType ObjectService::getServices( ::fwData::Object::sptr obj ) const
577 {
578  FW_DEPRECATED_MSG("'ObjectService::getServices(object)' is deprecated.", "20.0");
579  ServiceVectorType services;
580  ::fwCore::mt::ReadLock lock(m_containerMutex);
581 
582  ServiceContainerType::left_map::const_iterator firstElement = m_container.left.find(obj);
583  if(firstElement != m_container.left.end())
584  {
585  ServiceContainerType::left_map::const_iterator lastElement = m_container.left.upper_bound(obj);
586  for (auto iter = firstElement; iter != lastElement; ++iter)
587  {
588  services.insert( iter->second );
589  }
590  }
591  return services;
592 }
593 
594 //------------------------------------------------------------------------------
595 
596 bool ObjectService::has( ::fwData::Object::sptr obj, const std::string& srvType) const
597 {
598  FW_DEPRECATED_MSG("'ObjectService::has(object, srvType)' is deprecated.", "20.0");
599  bool hasServices = false;
600  ::fwCore::mt::ReadLock lock(m_containerMutex);
601  ServiceContainerType::left_map::const_iterator firstElement = m_container.left.find(obj);
602  if( firstElement != m_container.left.end())
603  {
604  ServiceContainerType::left_map::const_iterator lastElement = m_container.left.upper_bound(obj);
605  for (auto iter = firstElement; iter != lastElement; ++iter)
606  {
607  if( iter->second->isA(srvType))
608  {
609  hasServices = true;
610  break;
611  }
612  }
613  }
614  return hasServices;
615 }
616 
617 //------------------------------------------------------------------------------
618 
619 } // namespace registry
620 } // namespace fwServices
Contains fwAtomsFilter::registry details.
std::set< std::shared_ptr< SERVICE > > getServices()
Wraps ObjectService::getServices.
FWSERVICES_API void unregisterService(::fwServices::IService::sptr service)
Remove the service (service) from the m_container.
#define OSLM_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:310
#define OSLM_DEBUG_IF(message, cond)
Definition: spyLog.hpp:245
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
#define SLM_DEBUG_IF(message, cond)
Definition: spyLog.hpp:243
Namespace fwServices is dedicated to (mimic) the dynamic affectation of methods to (pure data) object...
FWSERVICES_API void unregisterServiceOutput(const ::fwServices::IService::KeyType &objKey,::fwServices::IService::sptr service)
Emit the signal &#39;unregistered&#39;.
FWSERVICES_API bool has(::fwData::Object::sptr obj, const std::string &srvType)
return true if the object has at least one service of type srvType
FWSERVICES_API void swapService(::fwData::Object::sptr objDst,::fwServices::IService::sptr service)
Wraps ObjectService::swapService.
FWSERVICES_API std::string getRegistryInformation()
Wraps ObjectService::getRegistryInformation.
::boost::unique_lock< ReadWriteMutex > WriteLock
Defines a lock of write type for read/write mutex.
#define FW_DEPRECATED_MSG(message, version)
Use this macro when deprecating a function to warn the developer.
Definition: spyLog.hpp:360
FWSERVICES_API::fwServices::registry::ObjectService::ObjectVectorType getObjects()
Wraps ObjectService::getObjects.
FWSERVICES_API::fwData::Object::csptr getRegistered(const ::fwServices::IService::KeyType &objKey,::fwServices::IService::AccessType access,::fwServices::IService::sptr service)
Return the object pointer of a key of a given service.
FWSERVICES_API void registerService(::fwServices::IService::sptr service)
Register the service alone.
#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
::boost::shared_lock< ReadWriteMutex > ReadLock
Defines a lock of read type for read/write mutex.
FWSERVICES_API void registerServiceOutput(::fwData::Object::sptr obj, const ::fwServices::IService::KeyType &objKey,::fwServices::IService::sptr service)
Emit the signal &#39;registered&#39;.
FWSERVICES_API void registerServiceInput(::fwData::Object::csptr obj, const ::fwServices::IService::KeyType &objKey,::fwServices::IService::sptr service)
Register the service (service) for the input object (obj) at the given service key. It also updates IService::m_associatedObject of service to point to obj removal at obj destruction.
FWSERVICES_API bool isRegistered(const ::fwServices::IService::KeyType &objKey,::fwServices::IService::AccessType access,::fwServices::IService::sptr service)
Return true if a key is registered for a given service.
#define SLM_WARN_IF(message, cond)
Definition: spyLog.hpp:265