瀏覽代碼

Merge branch 'factory-expose-utility-functions'

* factory-expose-utility-functions:
  Expose utility functions in the factories
Julien Finet 13 年之前
父節點
當前提交
72e42e0fad

+ 11 - 11
Libs/Core/Testing/Cpp/ctkAbstractLibraryFactoryTest1.cpp

@@ -98,44 +98,44 @@ int ctkAbstractLibraryFactoryTest1(int argc, char * argv [])
   ctkDummyLibraryFactoryItem libraryFactory;
   libraryFactory.setVerbose(true);
 
-  bool res = libraryFactory.registerFileItem("fail", QFileInfo("foo/bar.txt"));
-  if (res)
+  QString itemKey  = libraryFactory.registerFileItem(QFileInfo("foo/bar.txt"));
+  if (!itemKey.isEmpty())
     {
     std::cerr << "ctkAbstractLibraryFactory::registerLibrary() registered bad file"
               << std::endl;
     return EXIT_FAILURE;
     }
 
-  res = libraryFactory.registerFileItem("lib", file);
-  if (!res || libraryFactory.itemKeys().count() != 1)
+  itemKey = libraryFactory.registerFileItem(file);
+  if (itemKey.isEmpty() || libraryFactory.itemKeys().count() != 1)
     {
     std::cerr << "ctkAbstractLibraryFactory::registerLibrary() failed"
               << libraryFactory.itemKeys().count() << std::endl;
     return EXIT_FAILURE;
     }
-  // register twice must return false
-  res = libraryFactory.registerFileItem("lib", file);
-  if (res || libraryFactory.itemKeys().count() != 1)
+  // register twice must be a no-op
+  itemKey = libraryFactory.registerFileItem(file);
+  if (itemKey.isEmpty() || libraryFactory.itemKeys().count() != 1)
     {
     std::cerr << "ctkAbstractLibraryFactory::registerLibrary() failed"
               << libraryFactory.itemKeys().count() << std::endl;
     return EXIT_FAILURE;
     }
-  if (QFileInfo(libraryFactory.path("lib")) != file)
+  if (QFileInfo(libraryFactory.path(itemKey)) != file)
     {
     std::cerr << "ctkAbstractLibraryFactory::registerLibrary() failed"
-              << libraryFactory.path("lib").toStdString() << std::endl;
+              << libraryFactory.path(itemKey).toStdString() << std::endl;
     return EXIT_FAILURE;
     }
 
-  ctkDummyLibrary* library = libraryFactory.instantiate("lib");
+  ctkDummyLibrary* library = libraryFactory.instantiate(itemKey);
   if (library == 0)
     {
     std::cerr << "ctkAbstractLibraryFactory::instantiate() failed" << std::endl;
     return EXIT_FAILURE;
     }
 
-  libraryFactory.uninstantiate("lib");
+  libraryFactory.uninstantiate(itemKey);
   return EXIT_SUCCESS;
 }
 

+ 21 - 20
Libs/Core/Testing/Cpp/ctkAbstractPluginFactoryTest1.cpp

@@ -63,59 +63,60 @@ int ctkAbstractPluginFactoryTest1(int argc, char * argv [])
   ctkAbstractPluginFactory< ctkDummyPlugin > pluginFactory;
   pluginFactory.setVerbose(true);
 
-  bool res = pluginFactory.registerFileItem("fail", QFileInfo("foo/bar.txt"));
-  if (res)
+  QString itemKey = pluginFactory.registerFileItem(QFileInfo("foo/bar.txt"));
+  if (!itemKey.isEmpty())
     {
     std::cerr << "ctkAbstractPluginFactory::registerLibrary() registered bad file"
               << std::endl;
     return EXIT_FAILURE;
     }
-  
-  res = pluginFactory.registerFileItem("lib", file);
-  if (!res || pluginFactory.itemKeys().count() != 1)
+
+  itemKey = pluginFactory.registerFileItem(file);
+  if (itemKey.isEmpty() || pluginFactory.itemKeys().count() != 1)
     {
-    std::cerr << "ctkAbstractPluginFactory::registerLibrary() failed"
+    std::cerr << __LINE__ << ": ctkAbstractPluginFactory::registerLibrary() failed: "
               << pluginFactory.itemKeys().count() << std::endl;
     return EXIT_FAILURE;
     }
   // register twice must return false
-  res = pluginFactory.registerFileItem("lib", file);
-  if (res || pluginFactory.itemKeys().count() != 1)
+  itemKey = pluginFactory.registerFileItem(file);
+  if (itemKey.isEmpty() || pluginFactory.itemKeys().count() != 1)
     {
-    std::cerr << "ctkAbstractPluginFactory::registerLibrary() failed"
+    std::cerr << __LINE__ << ": ctkAbstractPluginFactory::registerLibrary() failed: "
+              << qPrintable(itemKey) << " count: "
               << pluginFactory.itemKeys().count() << std::endl;
     return EXIT_FAILURE;
     }
-  if (QFileInfo(pluginFactory.path("lib")) != file)
+  if (QFileInfo(pluginFactory.path(itemKey)) != file)
     {
-    std::cerr << "ctkAbstractPluginFactory::registerLibrary() failed"
-              << pluginFactory.path("lib").toStdString() << std::endl;
+    std::cerr << __LINE__ << ": ctkAbstractPluginFactory::registerLibrary() failed: "
+              << pluginFactory.path(itemKey).toStdString() << std::endl;
     return EXIT_FAILURE;
     }
 
-  ctkDummyPlugin* plugin = pluginFactory.instantiate("lib");
+  ctkDummyPlugin* plugin = pluginFactory.instantiate(itemKey);
   if (plugin == 0)
     {
-    std::cerr << "ctkAbstractPluginFactory::instantiate() failed" << std::endl;
+    std::cerr << __LINE__ << ": ctkAbstractPluginFactory::instantiate() failed" << std::endl;
     return EXIT_FAILURE;
     }
 
-  pluginFactory.uninstantiate("lib");
-  
+  pluginFactory.uninstantiate(itemKey);
+
   // ctkDummyPlugin is not a QPushButton, it should fail then.
   ctkAbstractPluginFactory< QTimer > buttonPluginFactory;
   buttonPluginFactory.setVerbose(true);
   // it should register but fail while instanciating
-  res = buttonPluginFactory.registerFileItem("foo", file);
-  if (!res || buttonPluginFactory.itemKeys().count() != 1)
+  itemKey = buttonPluginFactory.registerFileItem(file);
+  if (itemKey.isEmpty() || buttonPluginFactory.itemKeys().count() != 1)
     {
-    std::cerr << "ctkAbstractPluginFactory::registerLibrary() failed" << std::endl;
+    std::cerr << __LINE__ << ": ctkAbstractPluginFactory::registerLibrary() failed" << std::endl;
     return EXIT_FAILURE;
     }
   QTimer* timer = buttonPluginFactory.instantiate("foo");
   if (timer != 0)
     {
-    std::cerr << "ctkAbstractPluginFactory::instantiate() failed" << std::endl;
+    std::cerr << __LINE__ << ": ctkAbstractPluginFactory::instantiate() failed" << std::endl;
     return EXIT_FAILURE;
     }
   return EXIT_SUCCESS;

+ 9 - 0
Libs/Core/Testing/Cpp/ctkDummyPlugin.cpp

@@ -19,6 +19,7 @@
 =========================================================================*/
 
 // Qt includes
+#include <QDebug>
 #include <QtPlugin>
 
 // CTK includes
@@ -30,9 +31,17 @@ Q_EXPORT_PLUGIN2( ctkDummyPlugin , ctkDummyPlugin)
 ctkDummyPlugin::ctkDummyPlugin(QObject* parent)
   :QObject(parent)
 {
+  qDebug() << "ctkDummyPlugin()";
 }
 
+ctkDummyPlugin::~ctkDummyPlugin()
+{
+  qDebug() << "~ctkDummyPlugin()";
+}
+
+
 //-----------------------------------------------------------------------------
 void ctkDummyPlugin::dummyInterface()
 {
+  qDebug() << "dummyInterface()";
 }

+ 2 - 0
Libs/Core/Testing/Cpp/ctkDummyPlugin.h

@@ -36,6 +36,8 @@ class CTK_DUMMY_EXPORT ctkDummyPlugin: public QObject//, public ctkDummyInterfac
 //  Q_INTERFACES(ctkDummyInterface)
 public:
   ctkDummyPlugin(QObject* parent = 0);
+  ~ctkDummyPlugin();
+
   virtual void dummyInterface();
 };
 

+ 6 - 1
Libs/Core/ctkAbstractFactory.h

@@ -54,7 +54,8 @@ public:
   QStringList loadWarningStrings()const;
 
   BaseClassType* instantiate();
-  bool instantiated()const;
+  bool isInstantiated()const;
+  BaseClassType* instance()const;
   virtual void uninstantiate();
 
   void setVerbose(bool value);
@@ -110,6 +111,10 @@ public:
   /// The item corresponding to the key should have been registered before.
   virtual BaseClassType * instantiate(const QString& itemKey);
 
+  /// \brief Return the instance associated with \a itemKey if any, otherwise
+  /// return 0.
+  virtual BaseClassType * instance(const QString& itemKey);
+
   /// \brief Uninstanciate the object.
   /// Do nothing if the item given by the key has not be instantiated nor registered.
   void uninstantiate(const QString& itemKey);

+ 20 - 8
Libs/Core/ctkAbstractFactory.tpp

@@ -128,19 +128,22 @@ BaseClassType* ctkAbstractFactoryItem<BaseClassType>::instantiate()
 {
   this->clearInstantiateErrorStrings();
   this->clearInstantiateWarningStrings();
-  if (this->Instance)
-    {
-    return this->Instance;
-    }
   this->Instance = this->instanciator();
   return this->Instance;
 }
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
-bool ctkAbstractFactoryItem<BaseClassType>::instantiated()const 
+bool ctkAbstractFactoryItem<BaseClassType>::isInstantiated()const
+{
+  return (this->Instance != 0);
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+BaseClassType* ctkAbstractFactoryItem<BaseClassType>::instance()const
 {
-  return (this->Instance != 0); 
+  return this->Instance;
 }
 
 //----------------------------------------------------------------------------
@@ -205,8 +208,8 @@ BaseClassType* ctkAbstractFactory<BaseClassType>::instantiate(const QString& ite
   bool wasInstantiated = false;
   if (_item)
     {
-    wasInstantiated = _item->instantiated();
-    instance = _item->instantiate();
+    wasInstantiated = _item->isInstantiated();
+    instance = wasInstantiated ? _item->instance() : _item->instantiate();
     }
   if (!wasInstantiated)
     {
@@ -234,6 +237,15 @@ BaseClassType* ctkAbstractFactory<BaseClassType>::instantiate(const QString& ite
   return instance;
 }
 
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+BaseClassType* ctkAbstractFactory<BaseClassType>::instance(const QString& itemKey)
+{
+  ctkAbstractFactoryItem<BaseClassType>* factoryItem = this->item(itemKey);
+  return factoryItem ? factoryItem->instance() : 0;
+}
+
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
 void ctkAbstractFactory<BaseClassType>::uninstantiate(const QString& itemKey)

+ 10 - 5
Libs/Core/ctkAbstractFileBasedFactory.h

@@ -49,20 +49,25 @@ template<typename BaseClassType>
 class ctkAbstractFileBasedFactory : public ctkAbstractFactory<BaseClassType>
 {
 public:
+  virtual bool isValidFile(const QFileInfo& file)const;
+  QString itemKey(const QFileInfo& file)const;
+
+  /// Register the item and return the itemkey on success, otherwise return an
+  /// empty string.
+  QString registerFileItem(const QFileInfo& file);
+
   /// Get path associated with the library identified by \a key
   virtual QString path(const QString& key);
 
-  bool registerFileItem(const QFileInfo& file);
-  bool registerFileItem(const QString& key, const QFileInfo& file);
-
 protected:
   void registerAllFileItems(const QStringList& directories);
 
-  virtual bool isValidFile(const QFileInfo& file)const;
+  bool registerFileItem(const QString& key, const QFileInfo& file);
+
   virtual ctkAbstractFactoryItem<BaseClassType>* createFactoryFileBasedItem();
   virtual void initItem(ctkAbstractFactoryItem<BaseClassType>* item);
 
-  virtual QString fileNameToKey(const QString& objectName)const;
+  virtual QString fileNameToKey(const QString& path)const;
 };
 
 #include "ctkAbstractFileBasedFactory.tpp"

+ 13 - 4
Libs/Core/ctkAbstractFileBasedFactory.tpp

@@ -87,11 +87,20 @@ void ctkAbstractFileBasedFactory<BaseClassType>::registerAllFileItems(const QStr
 
 //-----------------------------------------------------------------------------
 template<typename BaseClassType>
-bool ctkAbstractFileBasedFactory<BaseClassType>
+QString ctkAbstractFileBasedFactory<BaseClassType>
+::itemKey(const QFileInfo& fileInfo)const
+{
+  return this->fileNameToKey(fileInfo.filePath());
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkAbstractFileBasedFactory<BaseClassType>
 ::registerFileItem(const QFileInfo& fileInfo)
 {
-  QString key = this->fileNameToKey(fileInfo.filePath());
-  return this->registerFileItem(key, fileInfo);
+  QString key = this->itemKey(fileInfo);
+  bool registered = this->registerFileItem(key, fileInfo);
+  return registered ? key : QString();
 }
 
 //-----------------------------------------------------------------------------
@@ -103,7 +112,7 @@ bool ctkAbstractFileBasedFactory<BaseClassType>
   if (this->item(key))
     {
     this->displayStatusMessage(QtWarningMsg, description, "Already registered", this->verbose());
-    return false;
+    return true;
     }
   if (this->sharedItem(key))
     {

+ 1 - 0
Libs/Core/ctkAbstractPluginFactory.h

@@ -36,6 +36,7 @@ class ctkFactoryPluginItem : public ctkAbstractFactoryFileBasedItem<BaseClassTyp
 public:
   virtual bool load();
   virtual QString loadErrorString()const;
+  virtual void uninstantiate();
 
 protected:
   virtual BaseClassType* instanciator();

+ 17 - 1
Libs/Core/ctkAbstractPluginFactory.tpp

@@ -52,12 +52,28 @@ bool ctkFactoryPluginItem<BaseClassType>::load()
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
 QString ctkFactoryPluginItem<BaseClassType>::loadErrorString()const
-{ 
+{
   return this->Loader.errorString();
 }
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
+void ctkFactoryPluginItem<BaseClassType>::uninstantiate()
+{
+  if (this->Instance == 0)
+    {
+    return;
+    }
+  // QPluginLoader::unload doc says: "don't try to delete the root component".
+  bool deleted = this->Loader.unload();
+  if (deleted)
+    {
+    this->Instance = 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
 BaseClassType* ctkFactoryPluginItem<BaseClassType>::instanciator()
 {
   //qDebug() << "PluginItem::instantiate - name:" << this->path();