Ejemplo n.º 1
0
void ctkServiceRegistration::setProperties(const ServiceProperties& props)
{
  Q_D(ctkServiceRegistration);
  if (!d) throw std::logic_error("ctkServiceRegistration object invalid");

  QMutexLocker lock(&d->eventLock);

  QSet<ctkServiceSlotEntry> before;
  // TBD, optimize the locking of services
  {
    QMutexLocker lock2(&d->plugin->fwCtx->globalFwLock);
    QMutexLocker lock3(&d->propsLock);

    if (d->available)
    {
      // NYI! Optimize the MODIFIED_ENDMATCH code
      int old_rank = d->properties.value(ctkPluginConstants::SERVICE_RANKING).toInt();
      before = d->plugin->fwCtx->listeners.getMatchingServiceSlots(d->reference);
      QStringList classes = d->properties.value(ctkPluginConstants::OBJECTCLASS).toStringList();
      qlonglong sid = d->properties.value(ctkPluginConstants::SERVICE_ID).toLongLong();
      d->properties = ctkServices::createServiceProperties(props, classes, sid);
      int new_rank = d->properties.value(ctkPluginConstants::SERVICE_RANKING).toInt();
      if (old_rank != new_rank)
      {
        d->plugin->fwCtx->services->updateServiceRegistrationOrder(*this, classes);
      }
    }
    else
    {
      throw std::logic_error("Service is unregistered");
    }
  }
  d->plugin->fwCtx->listeners.serviceChanged(
      d->plugin->fwCtx->listeners.getMatchingServiceSlots(d->reference),
      ctkServiceEvent(ctkServiceEvent::MODIFIED, d->reference), before);

  d->plugin->fwCtx->listeners.serviceChanged(
      before,
      ctkServiceEvent(ctkServiceEvent::MODIFIED_ENDMATCH, d->reference));
}
Ejemplo n.º 2
0
ctkServiceRegistration ctkServices::registerService(ctkPluginPrivate* plugin,
                             const QStringList& classes,
                             QObject* service,
                             const ctkDictionary& properties)
{
  if (service == 0)
  {
    throw std::invalid_argument("Can't register 0 as a service");
  }

  // Check if service implements claimed classes and that they exist.
  for (QStringListIterator i(classes); i.hasNext();)
  {
    QString cls = i.next();
    if (cls.isEmpty())
    {
      throw std::invalid_argument("Can't register as null class");
    }

    if (!(qobject_cast<ctkServiceFactory*>(service)))
    {
      if (!checkServiceClass(service, cls))
      {
        QString msg = QString("Service class %1 is not an instance of %2. Maybe you forgot the Q_INTERFACES macro in the service class.")
            .arg(service->metaObject()->className()).arg(cls);
        throw std::invalid_argument(msg.toStdString());
      }
    }
  }

  ctkServiceRegistration res(plugin, service,
                             createServiceProperties(properties, classes));
  {
    QMutexLocker lock(&mutex);
    services.insert(res, classes);
    for (QStringListIterator i(classes); i.hasNext(); )
    {
      QString currClass = i.next();
      QList<ctkServiceRegistration>& s = classServices[currClass];
      QList<ctkServiceRegistration>::iterator ip =
          std::lower_bound(s.begin(), s.end(), res, ServiceRegistrationComparator());
      s.insert(ip, res);
    }
  }

  ctkServiceReference r = res.getReference();
  plugin->fwCtx->listeners.serviceChanged(
      plugin->fwCtx->listeners.getMatchingServiceSlots(r),
      ctkServiceEvent(ctkServiceEvent::REGISTERED, r));
  return res;
}
Ejemplo n.º 3
0
void ctkServiceRegistration::unregister()
{
  Q_D(ctkServiceRegistration);
  if (!d) throw std::logic_error("ctkServiceRegistration object invalid");

  if (d->unregistering) return; // Silently ignore redundant unregistration.
  {
    QMutexLocker lock(&d->eventLock);
    if (d->unregistering) return;
    d->unregistering = true;

    if (d->available)
    {
      if (d->plugin)
      {
        d->plugin->fwCtx->services->removeServiceRegistration(*this);
      }
    }
    else
    {
      throw std::logic_error("Service is unregistered");
    }
  }

  if (d->plugin)
  {
     d->plugin->fwCtx->listeners.serviceChanged(
         d->plugin->fwCtx->listeners.getMatchingServiceSlots(d->reference),
         ctkServiceEvent(ctkServiceEvent::UNREGISTERING, d->reference));
  }

  {
    QMutexLocker lock(&d->eventLock);
    {
      QMutexLocker lock2(&d->propsLock);
      d->available = false;
      if (d->plugin)
      {
        for (QHashIterator<QSharedPointer<ctkPlugin>, QObject*> i(d->serviceInstances); i.hasNext();)
        {
          QObject* obj = i.next().value();
          try
          {
            // NYI, don't call inside lock
            qobject_cast<ctkServiceFactory*>(d->service)->ungetService(i.key(),
                                                                       *this,
                                                                       obj);
          }
          catch (const std::exception& ue)
          {
            ctkPluginFrameworkEvent pfwEvent(ctkPluginFrameworkEvent::ERROR, d->plugin->q_func().data(), ue);
            d->plugin->fwCtx->listeners
                .emitFrameworkEvent(pfwEvent);
          }
        }
      }
      d->plugin = 0;
      d->dependents.clear();
      d->service = 0;
      d->serviceInstances.clear();;
      d->unregistering = false;
    }
  }
}