浏览代码

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 <cstdlib>
 #include <iostream>
 #include <iostream>
 
 
+int ObjectConstructed = 0; 
+
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-class BaseClassHelperType
+class Object
 {
 {
 public:
 public:
+  Object()
+  {
+    ++ObjectConstructed;
+  }
+  ~Object()
+  {
+    --ObjectConstructed;
+  }
 };
 };
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-class FactoryItemHelper
+class ObjectFactoryItem : public ctkFactoryLibraryItem<Object>
 {
 {
 public:
 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);
   QApplication app(argc, argv);
 
 
-//  typedef ctkAbstractLibraryFactory < BaseClassHelperType, FactoryItemHelper >  FactoryType;
-//  FactoryType  ctkObject;
-
+  ObjectFactory factory;
+  factory.registerItems();
 
 
   return EXIT_SUCCESS;
   return EXIT_SUCCESS;
 }
 }

+ 2 - 5
Libs/Core/ctkAbstractFactory.h

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

+ 5 - 14
Libs/Core/ctkAbstractFactory.tpp

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

+ 13 - 10
Libs/Core/ctkAbstractLibraryFactory.h

@@ -38,7 +38,7 @@ protected:
   typedef typename QHash<QString, void*>::iterator       Iterator;
   typedef typename QHash<QString, void*>::iterator       Iterator;
 
 
 public:
 public:
-  explicit ctkFactoryLibraryItem(const QString& key, const QString& path);
+  explicit ctkFactoryLibraryItem(const QString& path);
   virtual ~ctkFactoryLibraryItem(){}
   virtual ~ctkFactoryLibraryItem(){}
   virtual bool load();
   virtual bool load();
   QString path()const;
   QString path()const;
@@ -66,7 +66,7 @@ private:
 };
 };
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
+template<typename BaseClassType>
 class ctkAbstractLibraryFactory : public ctkAbstractFactory<BaseClassType>
 class ctkAbstractLibraryFactory : public ctkAbstractFactory<BaseClassType>
 {
 {
 public:
 public:
@@ -78,17 +78,20 @@ public:
   /// 
   /// 
   /// Set the list of symbols
   /// Set the list of symbols
   void setSymbols(const QStringList& 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
   /// 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:
 private:
   ctkAbstractLibraryFactory(const ctkAbstractLibraryFactory &);  /// Not implemented
   ctkAbstractLibraryFactory(const ctkAbstractLibraryFactory &);  /// Not implemented

+ 41 - 24
Libs/Core/ctkAbstractLibraryFactory.tpp

@@ -29,9 +29,8 @@
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
 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)
   ,Path(_path)
 {
 {
 }
 }
@@ -124,50 +123,68 @@ void* ctkFactoryLibraryItem<BaseClassType>::symbolAddress(const QString& symbol)
 // ctkAbstractLibraryFactory methods
 // ctkAbstractLibraryFactory methods
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-template<typename BaseClassType, typename FactoryItemType>
-ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::ctkAbstractLibraryFactory()
+template<typename BaseClassType>
+ctkAbstractLibraryFactory<BaseClassType>::ctkAbstractLibraryFactory()
   :ctkAbstractFactory<BaseClassType>()
   :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) 
   const QStringList& symbols) 
 {
 {
   this->Symbols = 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;
     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
 #endif

+ 0 - 6
Libs/Core/ctkAbstractObjectFactory.h

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

+ 4 - 16
Libs/Core/ctkAbstractObjectFactory.tpp

@@ -32,13 +32,6 @@
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 template<typename BaseClassType, typename ClassType>
 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()
 bool ctkFactoryObjectItem<BaseClassType,ClassType>::load()
 {
 {
   this->instantiateObjectFunc = &instantiateObject<BaseClassType, ClassType>;
   this->instantiateObjectFunc = &instantiateObject<BaseClassType, ClassType>;
@@ -55,15 +48,10 @@ BaseClassType* ctkFactoryObjectItem<BaseClassType,ClassType>::instanciator()
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 // ctkAbstractObjectFactory methods
 // ctkAbstractObjectFactory methods
 
 
-//----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 template<typename BaseClassType>
 template<typename BaseClassType>
 ctkAbstractObjectFactory<BaseClassType>::ctkAbstractObjectFactory()
 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> > objectItem =
     QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> >(
     QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> >(
-      new ctkFactoryObjectItem<BaseClassType, ClassType>(key) );
+      new ctkFactoryObjectItem<BaseClassType, ClassType>() );
   objectItem->setVerbose(this->verbose());
   objectItem->setVerbose(this->verbose());
-  return this->registerItem(objectItem);
+  return this->registerItem(key, objectItem);
 }
 }
 
 
 #endif
 #endif

+ 6 - 11
Libs/Core/ctkAbstractPluginFactory.h

@@ -33,8 +33,7 @@ template<typename BaseClassType>
 class ctkFactoryPluginItem : public ctkAbstractFactoryItem<BaseClassType>
 class ctkFactoryPluginItem : public ctkAbstractFactoryItem<BaseClassType>
 {
 {
 public:
 public:
-  explicit ctkFactoryPluginItem(const QString& key, const QString& path);
-  virtual ~ctkFactoryPluginItem(){}
+  explicit ctkFactoryPluginItem(const QString& path);
   virtual bool load();
   virtual bool load();
   QString path()const;
   QString path()const;
   virtual QString loadErrorString()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>
 class ctkAbstractPluginFactory : public ctkAbstractFactory<BaseClassType>
 {
 {
 public:
 public:
-  /// 
   /// Constructor
   /// Constructor
   explicit ctkAbstractPluginFactory();
   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
   /// Register a plugin in the factory
   /// The parameter \a key passed by reference will be updated with the
   /// The parameter \a key passed by reference will be updated with the
   /// associated object name obtained using ::fileNameToKey()
   /// 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:
 private:
   ctkAbstractPluginFactory(const ctkAbstractPluginFactory &);  /// Not implemented
   ctkAbstractPluginFactory(const ctkAbstractPluginFactory &);  /// Not implemented

+ 23 - 25
Libs/Core/ctkAbstractPluginFactory.tpp

@@ -33,9 +33,8 @@
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
 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
 // 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
   // Check if already registered
   if (this->item(key))
   if (this->item(key))
     {
     {
     return false;
     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());
   _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
 #endif