浏览代码

ENH: Store the unique key only in the hashmap of ctkAbstractFactory

there is no need to store it in the Factory item as well.
The 2nd template in subclasses of ctkAbstractFactory is not ideal, it is
more flexible to use a virtual constructor for factory items.
Julien Finet 15 年之前
父节点
当前提交
b92e0804ab

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

@@ -28,22 +28,48 @@
 #include <cstdlib>
 #include <iostream>
 
+int ObjectConstructed = 0; 
+
 //-----------------------------------------------------------------------------
-class BaseClassHelperType
+class Object
 {
 public:
+  Object()
+  {
+    ++ObjectConstructed;
+  }
+  ~Object()
+  {
+    --ObjectConstructed;
+  }
 };
 
 //-----------------------------------------------------------------------------
-class FactoryItemHelper
+class ObjectFactoryItem : public ctkFactoryLibraryItem<Object>
 {
 public:
-  FactoryItemHelper( QString &, QString )
-    {
-    }
-  void setSymbols(const QStringList& )
-    {
-    }
+  ObjectFactoryItem(const QString& path)
+    :ctkFactoryLibraryItem<Object>(path)
+  {
+  }
+protected:
+  virtual Object* instanciator(){return new Object;}
+};
+
+//-----------------------------------------------------------------------------
+class ObjectFactory : public ctkAbstractLibraryFactory<Object>
+{
+public:
+  virtual void registerItems()
+  {
+    qDebug() << "Registering items";
+  }
+  
+protected:
+  virtual ctkFactoryLibraryItem<Object>* createFactoryLibraryItem(const QFileInfo& file)const
+  {
+    return new ObjectFactoryItem(file.filePath());
+  }
 };
 
 //-----------------------------------------------------------------------------
@@ -51,9 +77,8 @@ int ctkAbstractLibraryFactoryTest1(int argc, char * argv [] )
 {
   QApplication app(argc, argv);
 
-//  typedef ctkAbstractLibraryFactory < BaseClassHelperType, FactoryItemHelper >  FactoryType;
-//  FactoryType  ctkObject;
-
+  ObjectFactory factory;
+  factory.registerItems();
 
   return EXIT_SUCCESS;
 }

+ 2 - 5
Libs/Core/ctkAbstractFactory.h

@@ -41,7 +41,7 @@ template<typename BaseClassType>
 class ctkAbstractFactoryItem
 {
 public:
-  explicit ctkAbstractFactoryItem(const QString& key);
+  explicit ctkAbstractFactoryItem();
   virtual ~ctkAbstractFactoryItem(){}
   
   virtual QString loadErrorString()const;
@@ -51,8 +51,6 @@ public:
   bool instantiated()const;
   virtual void uninstantiate();
   
-  QString key()const;
-  
   void setVerbose(bool value);
   bool verbose()const;
 
@@ -62,7 +60,6 @@ protected:
   BaseClassType* Instance;
 
 private:
-  QString Key;
   bool Verbose;
 };
 
@@ -112,7 +109,7 @@ protected:
   /// 
   /// Call the load method associated with the item.
   /// If succesfully loaded, add it to the internal map.
-  bool registerItem(const QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > & item);
+  bool registerItem(const QString& key, const QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > & item);
 
   /// 
   /// Get a Factory item given its itemKey. Return 0 if any.

+ 5 - 14
Libs/Core/ctkAbstractFactory.tpp

@@ -32,9 +32,8 @@
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
-ctkAbstractFactoryItem<BaseClassType>::ctkAbstractFactoryItem(const QString& _key)
+ctkAbstractFactoryItem<BaseClassType>::ctkAbstractFactoryItem()
   :Instance()
-  ,Key(_key)
 {
   this->Verbose = false;
 }
@@ -65,14 +64,6 @@ bool ctkAbstractFactoryItem<BaseClassType>::instantiated()const
   return (this->Instance != 0); 
 }
 
-
-//----------------------------------------------------------------------------
-template<typename BaseClassType>
-QString ctkAbstractFactoryItem<BaseClassType>::key()const
-{ 
-  return this->Key; 
-}
-
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
 void ctkAbstractFactoryItem<BaseClassType>::uninstantiate()
@@ -156,11 +147,11 @@ QStringList ctkAbstractFactory<BaseClassType>::keys() const
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
-bool ctkAbstractFactory<BaseClassType>::registerItem(
+bool ctkAbstractFactory<BaseClassType>::registerItem(const QString& key,
   const QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > & _item)
 {
   // Sanity checks
-  if (!_item || _item->key().isEmpty() || this->item(_item->key()))
+  if (!_item || key.isEmpty() || this->item(key))
     {
     return false;
     }
@@ -175,13 +166,13 @@ bool ctkAbstractFactory<BaseClassType>::registerItem(
       }
     if (this->verbose())
       {
-      qCritical() << "Failed to load object:" << _item->key() << errorStr ;
+      qCritical() << "Failed to load object:" << key << errorStr ;
       }
     return false;
     }
   
   // Store its reference using a QSharedPointer
-  this->RegisteredItemMap[_item->key()] = _item;
+  this->RegisteredItemMap[key] = _item;
   return true;
 }
 

+ 13 - 10
Libs/Core/ctkAbstractLibraryFactory.h

@@ -38,7 +38,7 @@ protected:
   typedef typename QHash<QString, void*>::iterator       Iterator;
 
 public:
-  explicit ctkFactoryLibraryItem(const QString& key, const QString& path);
+  explicit ctkFactoryLibraryItem(const QString& path);
   virtual ~ctkFactoryLibraryItem(){}
   virtual bool load();
   QString path()const;
@@ -66,7 +66,7 @@ private:
 };
 
 //----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
+template<typename BaseClassType>
 class ctkAbstractLibraryFactory : public ctkAbstractFactory<BaseClassType>
 {
 public:
@@ -78,17 +78,20 @@ public:
   /// 
   /// Set the list of symbols
   void setSymbols(const QStringList& symbols);
-
-  ///
-  /// Return a name allowing to uniquely identify the library
-  /// By default, it return \a fileName
-  virtual QString fileNameToKey(const QString& fileName);
   
   /// 
   /// Register a plugin in the factory
-  /// The parameter \a key passed by reference will be updated with the
-  /// associated object name obtained using ::fileNameToKey()
-  virtual bool registerLibrary(const QFileInfo& file, QString& key);
+  /// The parameter \a key must be unique
+  bool registerLibrary(const QString& key, const QFileInfo& file);
+
+  /// 
+  /// Utility function to register a QLibrary
+  /// The parameter \a key must be unique
+  bool registerQLibrary(const QString& key, const QFileInfo& file);
+
+protected:
+  virtual ctkFactoryLibraryItem<BaseClassType>* createFactoryLibraryItem(
+    const QFileInfo& library)const;
 
 private:
   ctkAbstractLibraryFactory(const ctkAbstractLibraryFactory &);  /// Not implemented

+ 41 - 24
Libs/Core/ctkAbstractLibraryFactory.tpp

@@ -29,9 +29,8 @@
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
-ctkFactoryLibraryItem<BaseClassType>::ctkFactoryLibraryItem(const QString& _key,
-                                                            const QString& _path)
-  :ctkAbstractFactoryItem<BaseClassType>(_key)
+ctkFactoryLibraryItem<BaseClassType>::ctkFactoryLibraryItem(const QString& _path)
+  :ctkAbstractFactoryItem<BaseClassType>()
   ,Path(_path)
 {
 }
@@ -124,50 +123,68 @@ void* ctkFactoryLibraryItem<BaseClassType>::symbolAddress(const QString& symbol)
 // ctkAbstractLibraryFactory methods
 
 //-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::ctkAbstractLibraryFactory()
+template<typename BaseClassType>
+ctkAbstractLibraryFactory<BaseClassType>::ctkAbstractLibraryFactory()
   :ctkAbstractFactory<BaseClassType>()
 {
 }
   
 //-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::~ctkAbstractLibraryFactory()
+template<typename BaseClassType>
+ctkAbstractLibraryFactory<BaseClassType>::~ctkAbstractLibraryFactory()
 {
 }
 
 //-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-void ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::setSymbols(
+template<typename BaseClassType>
+void ctkAbstractLibraryFactory<BaseClassType>::setSymbols(
   const QStringList& symbols) 
 {
   this->Symbols = symbols; 
 }
 
 //-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-QString ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::fileNameToKey(
-  const QString& fileName)
+template<typename BaseClassType>
+bool ctkAbstractLibraryFactory<BaseClassType>::registerLibrary(
+  const QString& key, const QFileInfo& file)
 {
-  return fileName; 
+  QSharedPointer<ctkFactoryLibraryItem<BaseClassType> > itemToRegister =
+    QSharedPointer<ctkFactoryLibraryItem<BaseClassType> >(
+      this->createFactoryLibraryItem(file));
+      //new ctkFactoryLibraryItem<BaseClassType>(key, file.filePath()));
+  if (itemToRegister.isNull())
+    {
+    return false;
+    }
+  itemToRegister->setVerbose(this->verbose());
+  itemToRegister->setSymbols(this->Symbols);
+  return this->registerItem(key, itemToRegister);
 }
 
 //-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-bool ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::registerLibrary(
-  const QFileInfo& file, QString& key)
+template<typename BaseClassType>
+bool ctkAbstractLibraryFactory<BaseClassType>::registerQLibrary(
+  const QString& key, const QFileInfo& file)
 {
-  key = this->fileNameToKey(file.fileName());
-  // Check if already registered
-  if (this->item(key))
+  // Skip if current file isn't a library
+  if (!QLibrary::isLibrary(file.fileName()))
     {
     return false;
     }
-  QSharedPointer<FactoryItemType> _item =
-    QSharedPointer<FactoryItemType>(new FactoryItemType(key, file.filePath()));
-  _item->setVerbose(this->verbose());
-  _item->setSymbols(this->Symbols);
-  return this->registerItem(_item);
+  if (this->verbose())
+    {
+    qDebug() << "Attempt to register QLibrary:" << file.fileName();
+    }
+  return this->registerLibrary(key, file);
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkFactoryLibraryItem<BaseClassType>* ctkAbstractLibraryFactory<BaseClassType>::
+createFactoryLibraryItem(const QFileInfo& library)const
+{
+  Q_UNUSED(library);
+  return 0;
 }
 
 #endif

+ 0 - 6
Libs/Core/ctkAbstractObjectFactory.h

@@ -45,8 +45,6 @@ class ctkFactoryObjectItem : public ctkAbstractFactoryItem<BaseClassType>
 protected:
   typedef BaseClassType *(*InstantiateObjectFunc)();
 public:
-  explicit ctkFactoryObjectItem(const QString& key);
-  virtual ~ctkFactoryObjectItem(){}
   virtual bool load();
 protected:
   virtual BaseClassType* instanciator();
@@ -59,11 +57,7 @@ template<typename BaseClassType>
 class ctkAbstractObjectFactory : public ctkAbstractFactory<BaseClassType>
 {
 public:
-  /// 
-  /// Constructor/Desctructor
   explicit ctkAbstractObjectFactory();
-  virtual ~ctkAbstractObjectFactory();
-
   /// 
   /// Register an object in the factory
   template<typename ClassType>

+ 4 - 16
Libs/Core/ctkAbstractObjectFactory.tpp

@@ -32,13 +32,6 @@
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType, typename ClassType>
-ctkFactoryObjectItem<BaseClassType,ClassType>::ctkFactoryObjectItem(const QString& _key)
-  :ctkAbstractFactoryItem<BaseClassType>(_key)
-{
-}
-
-//----------------------------------------------------------------------------
-template<typename BaseClassType, typename ClassType>
 bool ctkFactoryObjectItem<BaseClassType,ClassType>::load()
 {
   this->instantiateObjectFunc = &instantiateObject<BaseClassType, ClassType>;
@@ -55,15 +48,10 @@ BaseClassType* ctkFactoryObjectItem<BaseClassType,ClassType>::instanciator()
 //----------------------------------------------------------------------------
 // ctkAbstractObjectFactory methods
 
-//----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 template<typename BaseClassType>
 ctkAbstractObjectFactory<BaseClassType>::ctkAbstractObjectFactory()
-{
-}
-
-//----------------------------------------------------------------------------
-template<typename BaseClassType>
-ctkAbstractObjectFactory<BaseClassType>::~ctkAbstractObjectFactory()
+:ctkAbstractFactory<BaseClassType>()
 {
 }
 
@@ -79,9 +67,9 @@ bool ctkAbstractObjectFactory<BaseClassType>::registerObject(const QString& key)
     }
   QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> > objectItem =
     QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> >(
-      new ctkFactoryObjectItem<BaseClassType, ClassType>(key) );
+      new ctkFactoryObjectItem<BaseClassType, ClassType>() );
   objectItem->setVerbose(this->verbose());
-  return this->registerItem(objectItem);
+  return this->registerItem(key, objectItem);
 }
 
 #endif

+ 6 - 11
Libs/Core/ctkAbstractPluginFactory.h

@@ -33,8 +33,7 @@ template<typename BaseClassType>
 class ctkFactoryPluginItem : public ctkAbstractFactoryItem<BaseClassType>
 {
 public:
-  explicit ctkFactoryPluginItem(const QString& key, const QString& path);
-  virtual ~ctkFactoryPluginItem(){}
+  explicit ctkFactoryPluginItem(const QString& path);
   virtual bool load();
   QString path()const;
   virtual QString loadErrorString()const;
@@ -48,25 +47,21 @@ private:
 };
 
 //----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType = ctkFactoryPluginItem<BaseClassType> >
+template<typename BaseClassType>
 class ctkAbstractPluginFactory : public ctkAbstractFactory<BaseClassType>
 {
 public:
-  /// 
   /// Constructor
   explicit ctkAbstractPluginFactory();
-  virtual ~ctkAbstractPluginFactory();
-
-  ///
-  /// Return a name allowing to uniquely identify the plugin
-  /// By default, it return \a fileName 
-  virtual QString fileNameToKey(const QString& fileName);
 
   ///
   /// Register a plugin in the factory
   /// The parameter \a key passed by reference will be updated with the
   /// associated object name obtained using ::fileNameToKey()
-  virtual bool registerLibrary(const QFileInfo& file, QString& key);
+  virtual bool registerLibrary(const QString& key, const QFileInfo& file);
+
+protected:
+  virtual ctkAbstractFactoryItem<BaseClassType>* createFactoryPluginItem(const QFileInfo& file);
 
 private:
   ctkAbstractPluginFactory(const ctkAbstractPluginFactory &);  /// Not implemented

+ 23 - 25
Libs/Core/ctkAbstractPluginFactory.tpp

@@ -33,9 +33,8 @@
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
-ctkFactoryPluginItem<BaseClassType>::ctkFactoryPluginItem(const QString& _key,
-                                                          const QString& _path)
-  :ctkAbstractFactoryItem<BaseClassType>(_key),Path(_path)
+ctkFactoryPluginItem<BaseClassType>::ctkFactoryPluginItem(const QString& _path)
+  :Path(_path)
 {
 }
 
@@ -93,39 +92,38 @@ BaseClassType* ctkFactoryPluginItem<BaseClassType>::instanciator()
 // ctkAbstractPluginFactory methods
 
 //----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-ctkAbstractPluginFactory<BaseClassType, FactoryItemType>::ctkAbstractPluginFactory():ctkAbstractFactory<BaseClassType>()
-{
-}
-
-//----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-ctkAbstractPluginFactory<BaseClassType, FactoryItemType>::~ctkAbstractPluginFactory()
-{
-}
-
-//-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-QString ctkAbstractPluginFactory<BaseClassType, FactoryItemType>::fileNameToKey(
-  const QString& fileName)
+template<typename BaseClassType>
+ctkAbstractPluginFactory<BaseClassType>::ctkAbstractPluginFactory()
+:ctkAbstractFactory<BaseClassType>()
 {
-  return fileName; 
 }
 
 //----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-bool ctkAbstractPluginFactory<BaseClassType, FactoryItemType>::registerLibrary(const QFileInfo& file, QString& key)
+template<typename BaseClassType>
+bool ctkAbstractPluginFactory<BaseClassType>::registerLibrary(const QString& key, const QFileInfo& file)
 {
-  key = this->fileNameToKey(file.fileName());
   // Check if already registered
   if (this->item(key))
     {
     return false;
     }
-  QSharedPointer<FactoryItemType> _item =
-    QSharedPointer<FactoryItemType>(new FactoryItemType(key, file.filePath()));
+  QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > _item =
+    QSharedPointer<ctkAbstractFactoryItem<BaseClassType> >(
+      this->createFactoryPluginItem(file));
+  if (_item.isNull())
+    {
+    return false;
+    }
+  
   _item->setVerbose(this->verbose());
-  return this->registerItem(_item);
+  return this->registerItem(key, _item);
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractFactoryItem<BaseClassType>* ctkAbstractPluginFactory<BaseClassType>::createFactoryPluginItem(const QFileInfo& file)
+{
+  return new ctkFactoryPluginItem<BaseClassType>(file.filePath());
 }
 
 #endif