Просмотр исходного кода

ENH: Add ctkAbstractFactory* classes and corresponding tests.

Note: The test only make sure the class can be instantiated. The different
methods still need to be covered.
Jean-Christophe Fillion-Robin лет назад: 15
Родитель
Сommit
1068b98f6f

+ 10 - 0
Libs/Core/CMakeLists.txt

@@ -39,6 +39,16 @@ SET(KIT_include_directories
   
 # Source files
 SET(KIT_SRCS
+  ctkAbstractFactory.h
+  ctkAbstractFactory.tpp
+  ctkAbstractObjectFactory.h
+  ctkAbstractObjectFactory.tpp
+  ctkAbstractPluginFactory.h
+  ctkAbstractPluginFactory.tpp
+  ctkAbstractQObjectFactory.h
+  ctkAbstractQObjectFactory.tpp
+  ctkAbstractLibraryFactory.h
+  ctkAbstractLibraryFactory.tpp
   ctkDependencyGraph.cpp
   ctkDependencyGraph.h
   ctkModelTester.cpp

+ 5 - 0
Libs/Core/Testing/Cpp/CMakeLists.txt

@@ -1,6 +1,11 @@
 SET(KIT ${PROJECT_NAME})
 
 CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
+  ctkAbstractFactoryTest1.cpp
+  ctkAbstractLibraryFactoryTest1.cpp
+  ctkAbstractObjectFactoryTest1.cpp
+  ctkAbstractPluginFactoryTest1.cpp
+  ctkAbstractQObjectFactoryTest1.cpp
   ctkModelTesterTest1.cpp
   ctkUtilsTest1.cpp
   ctkDependencyGraphTest1.cpp

+ 35 - 0
Libs/Core/Testing/Cpp/ctkAbstractFactoryTest1.cpp

@@ -0,0 +1,35 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkAbstractFactory.h"
+#include "ctkModelTester.h"
+
+// QT includes
+#include <QApplication>
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+int ctkAbstractFactoryTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkAbstractFactory< ctkModelTester >  qctkObject;
+
+
+  return EXIT_SUCCESS;
+}
+

+ 51 - 0
Libs/Core/Testing/Cpp/ctkAbstractLibraryFactoryTest1.cpp

@@ -0,0 +1,51 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkAbstractLibraryFactory.h"
+
+// QT includes
+#include <QApplication>
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+class BaseClassHelperType
+{
+public:
+};
+
+class FactoryItemHelper
+{
+public:
+  FactoryItemHelper( QString &, QString )
+    {
+    }
+  void setSymbols(const QStringList& )
+    {
+    }
+};
+
+int ctkAbstractLibraryFactoryTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+//  typedef ctkAbstractLibraryFactory < BaseClassHelperType, FactoryItemHelper >  FactoryType;
+//  FactoryType  ctkObject;
+
+
+  return EXIT_SUCCESS;
+}
+

+ 39 - 0
Libs/Core/Testing/Cpp/ctkAbstractObjectFactoryTest1.cpp

@@ -0,0 +1,39 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkAbstractObjectFactory.h"
+
+// QT includes
+#include <QApplication>
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+class BaseClassHelper
+{
+public:
+};
+
+int ctkAbstractObjectFactoryTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkAbstractObjectFactory< BaseClassHelper > ctkObject;
+
+
+  return EXIT_SUCCESS;
+}
+

+ 36 - 0
Libs/Core/Testing/Cpp/ctkAbstractPluginFactoryTest1.cpp

@@ -0,0 +1,36 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkAbstractPluginFactory.h"
+#include "ctkModelTester.h"
+
+// QT includes
+#include <QApplication>
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+
+int ctkAbstractPluginFactoryTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkAbstractPluginFactory< ctkModelTester > ctkObject;
+
+
+  return EXIT_SUCCESS;
+}
+

+ 35 - 0
Libs/Core/Testing/Cpp/ctkAbstractQObjectFactoryTest1.cpp

@@ -0,0 +1,35 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkAbstractQObjectFactory.h"
+#include "ctkModelTester.h"
+
+// QT includes
+#include <QApplication>
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+int ctkAbstractQObjectFactoryTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkAbstractQObjectFactory< ctkModelTester > ctkObject;
+
+
+  return EXIT_SUCCESS;
+}
+

+ 101 - 0
Libs/Core/ctkAbstractFactory.h

@@ -0,0 +1,101 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractFactory_h
+#define __ctkAbstractFactory_h
+
+#include <QString>
+#include <QHash>
+#include <QSharedPointer>
+#include <QStringList>
+
+#ifdef _MSC_VER
+  /// 4505: 'ctkAbstractFactoryItem<BaseClassType>::loadErrorString' :
+  ///       unreferenced local function has been removed
+# pragma warning(disable: 4505)
+#endif
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+class ctkAbstractFactoryItem
+{
+public:
+  explicit ctkAbstractFactoryItem(const QString& key);
+  
+  virtual QString loadErrorString()const;
+  virtual bool load() = 0;
+  BaseClassType* instantiate();
+  bool instantiated();
+  QString key();
+  virtual void uninstantiate();
+protected:
+  virtual BaseClassType* instanciator() = 0;
+  BaseClassType* Instance;
+private:
+  QString Key;
+};
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+class ctkAbstractFactory
+{
+protected:
+  typedef typename QHash<QString, QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > >::const_iterator ConstIterator;
+  typedef typename QHash<QString, QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > >::iterator       Iterator;
+
+public:
+  /// 
+  /// Constructor/Desctructor
+  explicit ctkAbstractFactory();
+  virtual ~ctkAbstractFactory();
+  virtual void printAdditionalInfo();
+
+  /// 
+  /// Create an instance of the object
+  virtual BaseClassType * instantiate(const QString& itemKey);
+
+  /// 
+  /// Uninstanciate the object
+  void uninstantiate(const QString& itemKey);
+
+  /// 
+  /// Get list of all registered item names
+  QStringList names() const;
+
+  /// 
+  /// Register items with the factory
+  /// Method provided for convenience - Should be overloaded in subclasse
+  virtual void registerItems(){}
+
+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);
+
+  /// 
+  /// Get a Factory item given its itemKey. Return 0 if any.
+  ctkAbstractFactoryItem<BaseClassType> * item(const QString& itemKey)const;
+
+private:
+  ctkAbstractFactory(const ctkAbstractFactory &); /// Not implemented
+  void operator=(const ctkAbstractFactory&); /// Not implemented
+
+  QHash<QString, QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > > RegisteredItemMap;
+};
+
+#include "ctkAbstractFactory.tpp"
+
+#endif

+ 166 - 0
Libs/Core/ctkAbstractFactory.tpp

@@ -0,0 +1,166 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractFactory_tpp
+#define __ctkAbstractFactory_tpp
+
+#include "ctkAbstractFactory.h"
+#include <QDebug>
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractFactoryItem<BaseClassType>::ctkAbstractFactoryItem(const QString& _key)
+  :Instance()
+  ,Key(_key)
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkAbstractFactoryItem<BaseClassType>::loadErrorString()const
+{ 
+  return QString(); 
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>  
+BaseClassType* ctkAbstractFactoryItem<BaseClassType>::instantiate()
+{
+  if (this->Instance)
+    {
+    return this->Instance;
+    }
+  this->Instance = this->instanciator();
+  return this->Instance;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+bool ctkAbstractFactoryItem<BaseClassType>::instantiated() 
+{
+  return (this->Instance != 0); 
+}
+
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkAbstractFactoryItem<BaseClassType>::key() 
+{ 
+  return this->Key; 
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactoryItem<BaseClassType>::uninstantiate()
+{
+  if (!this->Instance)
+    {
+    return;
+    }
+  delete this->Instance;
+  // Make sure the pointer is set to 0. Doing so, Will prevent attempt to
+  // delete unextising object if uninstantiate() methods is called multiple times.
+  this->Instance = 0; 
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractFactory<BaseClassType>::ctkAbstractFactory()
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractFactory<BaseClassType>::~ctkAbstractFactory()
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactory<BaseClassType>::printAdditionalInfo()
+{
+  qDebug() << "ctkAbstractFactory<BaseClassType> (" << this << ")";
+  // TODO
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+BaseClassType* ctkAbstractFactory<BaseClassType>::instantiate(const QString& itemKey)
+{
+  ctkAbstractFactoryItem<BaseClassType>* _item = this->item(itemKey);
+  return (_item ? _item->instantiate() : 0);
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactory<BaseClassType>::uninstantiate(const QString& itemKey)
+{
+  ctkAbstractFactoryItem<BaseClassType> * _item = this->item(itemKey);
+  if (!_item)
+    {
+    return;
+    }
+  _item->uninstantiate();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QStringList ctkAbstractFactory<BaseClassType>::names() const
+{
+  // Since by construction, we checked if a name was already in the QHash,
+  // there is no need to call 'uniqueKeys'
+  return this->RegisteredItemMap.keys();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+bool ctkAbstractFactory<BaseClassType>::registerItem(
+  const QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > & _item)
+{
+  // Sanity checks
+  if (!_item || _item->key().isEmpty() || this->item(_item->key()))
+    {
+    return false;
+    }
+  
+  // Attempt to load it
+  if (!_item->load())
+    {
+    QString errorStr;
+    if (!_item->loadErrorString().isEmpty())
+      {
+      errorStr = " - " + _item->loadErrorString();
+      }
+    qCritical() << "Failed to load object:" << _item->key() << errorStr ;
+    return false;
+    }
+  
+  // Store its reference using a QSharedPointer
+  this->RegisteredItemMap[_item->key()] = _item;
+  return true;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractFactoryItem<BaseClassType> * ctkAbstractFactory<BaseClassType>::item(const QString& itemKey)const
+{
+  ConstIterator iter = this->RegisteredItemMap.find(itemKey);
+  if ( iter == this->RegisteredItemMap.constEnd())
+    {
+    return 0;
+    }
+  return iter.value().data();
+}
+
+#endif

+ 87 - 0
Libs/Core/ctkAbstractLibraryFactory.h

@@ -0,0 +1,87 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractLibraryFactory_h
+#define __ctkAbstractLibraryFactory_h
+
+#include "ctkAbstractFactory.h"
+
+#include <QFileInfo>
+#include <QLibrary>
+#include <QStringList>
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+class ctkFactoryLibraryItem : public ctkAbstractFactoryItem<BaseClassType>
+{
+protected:
+  typedef typename QHash<QString, void*>::const_iterator ConstIterator;
+  typedef typename QHash<QString, void*>::iterator       Iterator;
+
+public:
+  explicit ctkFactoryLibraryItem(const QString& key, const QString& path);
+  virtual bool load();
+  QString path()const;
+  virtual QString loadErrorString()const;
+
+  void setSymbols(const QStringList& symbols);
+
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Resolve symbols
+  void resolve();
+  
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Get symbol address
+  void* symbolAddress(const QString& symbol)const;
+
+private:
+  QLibrary              Library;
+  QString               Path;
+  QHash<QString, void*> ResolvedSymbols;
+  QStringList           Symbols;
+};
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType, typename FactoryItemType>
+class ctkAbstractLibraryFactory : public ctkAbstractFactory<BaseClassType>
+{
+public:
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Constructor
+  explicit ctkAbstractLibraryFactory();
+  virtual ~ctkAbstractLibraryFactory();
+
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Set the list of symbols
+  void setSymbols(const QStringList& symbols);
+
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Register a plugin in the factory
+  virtual bool registerLibrary(const QFileInfo& file, QString& key);
+
+private:
+  ctkAbstractLibraryFactory(const ctkAbstractLibraryFactory &);  /// Not implemented
+  void operator=(const ctkAbstractLibraryFactory&); /// Not implemented
+
+  QStringList Symbols;
+};
+
+#include "ctkAbstractLibraryFactory.tpp"
+
+#endif

+ 143 - 0
Libs/Core/ctkAbstractLibraryFactory.tpp

@@ -0,0 +1,143 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractLibraryFactory_tpp
+#define __ctkAbstractLibraryFactory_tpp
+
+// CTK includes
+#include "ctkAbstractFactory.h"
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkFactoryLibraryItem<BaseClassType>::ctkFactoryLibraryItem(const QString& _key,
+                                                            const QString& _path)
+  :ctkAbstractFactoryItem<BaseClassType>(_key)
+  ,Path(_path)
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+bool ctkFactoryLibraryItem<BaseClassType>::load()
+{
+  this->Library.setFileName(this->path());
+  bool loaded = this->Library.load();
+  if (loaded)
+    {
+    this->resolve();
+    return true;
+    }
+  return false;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkFactoryLibraryItem<BaseClassType>::path()const
+{ 
+  return this->Path; 
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkFactoryLibraryItem<BaseClassType>::loadErrorString()const
+{ 
+  return this->Library.errorString();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkFactoryLibraryItem<BaseClassType>::setSymbols(const QStringList& symbols)
+{ 
+  this->Symbols = symbols; 
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkFactoryLibraryItem<BaseClassType>::resolve()
+{
+  foreach(const QString& symbol, this->Symbols)
+    {
+    // Sanity checks
+    if (symbol.isEmpty()) 
+      { 
+      continue; 
+      }
+      
+    // Make sure the symbols haven't been registered
+    if (this->ResolvedSymbols.contains(symbol))
+      {
+      qWarning() << "Symbol '" << symbol << "' already resolved - Path:" << this->Path;
+      continue;
+      }
+    
+    void * resolvedSymbol = this->Library.resolve(symbol.toLatin1());
+    if (!resolvedSymbol)
+      {
+      qWarning() << "Failed to resolve symbol '" << symbol << "' - Path:" << this->Path;
+      }
+    this->ResolvedSymbols[symbol] = resolvedSymbol;
+    }
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType>
+void* ctkFactoryLibraryItem<BaseClassType>::symbolAddress(const QString& symbol)const
+{
+  ConstIterator iter = this->ResolvedSymbols.find(symbol);
+  
+  Q_ASSERT(iter != this->ResolvedSymbols.constEnd());
+  if ( iter == this->ResolvedSymbols.constEnd())
+    {
+    return 0;
+    }
+  return iter.value();
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType, typename FactoryItemType>
+ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::ctkAbstractLibraryFactory()
+  :ctkAbstractFactory<BaseClassType>()
+{
+}
+  
+//-----------------------------------------------------------------------------
+template<typename BaseClassType, typename FactoryItemType>
+ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::~ctkAbstractLibraryFactory()
+{
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType, typename FactoryItemType>
+void ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::setSymbols(const QStringList& symbols) 
+{
+  this->Symbols = symbols; 
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType, typename FactoryItemType>
+bool ctkAbstractLibraryFactory<BaseClassType, FactoryItemType>::registerLibrary(const QFileInfo& file, QString& key)
+{
+  key = file.fileName();
+  // Check if already registered
+  if (this->item(key))
+    {
+    return false;
+    }
+  QSharedPointer<FactoryItemType> _item =
+    QSharedPointer<FactoryItemType>(new FactoryItemType(key, file.filePath()));
+  _item->setSymbols(this->Symbols);
+  return this->registerItem(_item);
+}
+
+#endif

+ 72 - 0
Libs/Core/ctkAbstractObjectFactory.h

@@ -0,0 +1,72 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractObjectFactory_h
+#define __ctkAbstractObjectFactory_h
+
+#include "ctkAbstractFactory.h"
+
+#include <QDebug>
+
+//----------------------------------------------------------------------------
+namespace{
+  /// 
+  /// Function in charge of instanciating an object of type: ClassType
+  template<typename BaseClassType, typename ClassType>
+    BaseClassType *instantiateObject()
+  {
+    return new ClassType;
+  }
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType, typename ClassType>
+class ctkFactoryObjectItem : public ctkAbstractFactoryItem<BaseClassType>
+{
+protected:
+  typedef BaseClassType *(*InstantiateObjectFunc)();
+public:
+  explicit ctkFactoryObjectItem(const QString& key);
+  virtual bool load();
+protected:
+  virtual BaseClassType* instanciator();
+private:
+  InstantiateObjectFunc instantiateObjectFunc;
+};
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+class ctkAbstractObjectFactory : public ctkAbstractFactory<BaseClassType>
+{
+public:
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Constructor/Desctructor
+  explicit ctkAbstractObjectFactory();
+  virtual ~ctkAbstractObjectFactory();
+
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Register an object in the factory
+  template<typename ClassType>
+  bool registerObject(const QString& key);
+
+private:
+  ctkAbstractObjectFactory(const ctkAbstractObjectFactory &);  /// Not implemented
+  void operator=(const ctkAbstractObjectFactory&); /// Not implemented
+};
+
+#include "ctkAbstractObjectFactory.tpp"
+
+#endif

+ 74 - 0
Libs/Core/ctkAbstractObjectFactory.tpp

@@ -0,0 +1,74 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractObjectFactory_tpp
+#define __ctkAbstractObjectFactory_tpp
+
+// CTK includes
+#include "ctkAbstractObjectFactory.h"
+
+// QT includes
+#include <QDebug>
+
+//----------------------------------------------------------------------------
+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>;
+  return true;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType, typename ClassType>
+BaseClassType* ctkFactoryObjectItem<BaseClassType,ClassType>::instanciator()
+{
+  return this->instantiateObjectFunc();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractObjectFactory<BaseClassType>::ctkAbstractObjectFactory()
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractObjectFactory<BaseClassType>::~ctkAbstractObjectFactory()
+{
+}
+
+//-----------------------------------------------------------------------------
+template<typename BaseClassType>
+template<typename ClassType>
+bool ctkAbstractObjectFactory<BaseClassType>::registerObject(const QString& key)
+{
+  // Check if already registered
+  if (this->item(key))
+    {
+    return false;
+    }
+  QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> > objectItem =
+    QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> >(
+      new ctkFactoryObjectItem<BaseClassType, ClassType>(key) );
+  return this->registerItem(objectItem);
+}
+
+#endif

+ 62 - 0
Libs/Core/ctkAbstractPluginFactory.h

@@ -0,0 +1,62 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractPluginFactory_h
+#define __ctkAbstractPluginFactory_h
+
+#include "ctkAbstractFactory.h"
+
+#include <QPluginLoader>
+#include <QFileInfo>
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+class ctkFactoryPluginItem : public ctkAbstractFactoryItem<BaseClassType>
+{
+public:
+  explicit ctkFactoryPluginItem(const QString& key, const QString& path);
+  virtual bool load();
+  QString path()const;
+  virtual QString loadErrorString()const;
+
+protected:
+  virtual BaseClassType* instanciator();
+
+private:
+  QPluginLoader    Loader;
+  QString          Path;
+};
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType, typename FactoryItemType = ctkFactoryPluginItem<BaseClassType> >
+class ctkAbstractPluginFactory : public ctkAbstractFactory<BaseClassType>
+{
+public:
+  /// 
+  /// Constructor
+  explicit ctkAbstractPluginFactory();
+  virtual ~ctkAbstractPluginFactory();
+
+  /// 
+  /// Register a plugin in the factory
+  virtual bool registerLibrary(const QFileInfo& file, QString& key);
+
+private:
+  ctkAbstractPluginFactory(const ctkAbstractPluginFactory &);  /// Not implemented
+  void operator=(const ctkAbstractPluginFactory&); /// Not implemented
+};
+
+#include "ctkAbstractPluginFactory.tpp"
+
+#endif

+ 104 - 0
Libs/Core/ctkAbstractPluginFactory.tpp

@@ -0,0 +1,104 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractPluginFactory_tpp
+#define __ctkAbstractPluginFactory_tpp
+
+// CTK includes
+#include "ctkAbstractPluginFactory.h"
+
+// QT includes
+#include <QPluginLoader>
+#include <QDebug>
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkFactoryPluginItem<BaseClassType>::ctkFactoryPluginItem(const QString& _key,
+                                                            const QString& _path)
+  :ctkAbstractFactoryItem<BaseClassType>(_key),Path(_path)
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+bool ctkFactoryPluginItem<BaseClassType>::load()
+{
+  this->Loader.setFileName(this->path());
+  return this->Loader.load();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkFactoryPluginItem<BaseClassType>::path()const
+{ 
+  return this->Path; 
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QString ctkFactoryPluginItem<BaseClassType>::loadErrorString()const
+{ 
+  return this->Loader.errorString();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+BaseClassType* ctkFactoryPluginItem<BaseClassType>::instanciator()
+{
+  //qDebug() << "PluginItem::instantiate - name:" << this->path();
+  QObject * object = this->Loader.instance();
+  if (!object)
+    {
+    qWarning() << "Failed to instantiate plugin:" << this->path();
+    return 0;
+    }
+  BaseClassType* castedObject = qobject_cast<BaseClassType*>(object);
+  if (!castedObject)
+    {
+    qWarning() << "Failed to access interface [" << BaseClassType::staticMetaObject.className()
+               << "] in plugin:" << this->path();
+    delete object; // Clean memory
+    return 0;
+    }
+  return castedObject;
+}
+
+//----------------------------------------------------------------------------
+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>
+bool ctkAbstractPluginFactory<BaseClassType, FactoryItemType>::registerLibrary(const QFileInfo& file, QString& key)
+{
+  key = file.fileName();
+  // Check if already registered
+  if (this->item(key))
+    {
+    return false;
+    }
+  QSharedPointer<FactoryItemType> _item =
+    QSharedPointer<FactoryItemType>(new FactoryItemType(key, file.filePath()));
+  return this->registerItem(_item);
+}
+
+#endif

+ 57 - 0
Libs/Core/ctkAbstractQObjectFactory.h

@@ -0,0 +1,57 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractQObjectFactory_h
+#define __ctkAbstractQObjectFactory_h
+
+#include "ctkAbstractObjectFactory.h"
+
+#include <QDebug>
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+class ctkAbstractQObjectFactory : public ctkAbstractObjectFactory<BaseClassType>
+{
+public:
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Constructor/Desctructor
+  explicit ctkAbstractQObjectFactory();
+  virtual ~ctkAbstractQObjectFactory();
+
+  //----------------------------------------------------------------------------
+  /// 
+  /// Create an instance of the object
+  virtual BaseClassType * instantiate(const QString& itemKey);
+
+  //----------------------------------------------------------------------------
+  /// 
+  /// Uninstanciate the object
+  virtual void uninstantiate(const QString& itemKey);
+
+  //-----------------------------------------------------------------------------
+  /// 
+  /// Register an object in the factory
+  /// Note: The parameter 'key' passed by reference will be updated with the associated object name
+  template<typename ClassType>
+  bool registerQObject(QString& key);
+
+private:
+  ctkAbstractQObjectFactory(const ctkAbstractQObjectFactory &);  /// Not implemented
+  void operator=(const ctkAbstractQObjectFactory&); /// Not implemented
+};
+
+#include "ctkAbstractQObjectFactory.tpp"
+
+#endif

+ 59 - 0
Libs/Core/ctkAbstractQObjectFactory.tpp

@@ -0,0 +1,59 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __ctkAbstractQObjectFactory_tpp
+#define __ctkAbstractQObjectFactory_tpp
+
+// CTK includes
+#include "ctkAbstractObjectFactory.h"
+
+// QT includes
+#include <QDebug>
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractQObjectFactory<BaseClassType>::ctkAbstractQObjectFactory()
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+ctkAbstractQObjectFactory<BaseClassType>::~ctkAbstractQObjectFactory()
+{
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+BaseClassType* ctkAbstractQObjectFactory<BaseClassType>::instantiate(const QString& itemKey)
+{
+  return this->ctkAbstractObjectFactory<BaseClassType>::instantiate(itemKey);
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractQObjectFactory<BaseClassType>::uninstantiate(const QString& itemKey)
+{
+  this->ctkAbstractObjectFactory<BaseClassType>::uninstantiate(itemKey);
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+template<typename ClassType>
+bool ctkAbstractQObjectFactory<BaseClassType>::registerQObject(QString& key)
+{
+  key = QString::fromLatin1(ClassType::staticMetaObject.className());
+  return this->ctkAbstractObjectFactory<BaseClassType>::template registerObject<ClassType>(key);
+}
+
+#endif