Object Factories

Bill Hoffman bill.hoffman at kitware.com
Mon Oct 11 17:40:40 EDT 1999


<x-flowed>OBJECT FACTORY OVERVIEW:

This is a message to describe the new object factory feature recently added
to VTK.  The object factories have the following benefits:

- Allow sub-classes to be used in place of parent classes in existing code.

- Dynamic loading of new object implementations.

- Extensions to compiled and linked vtk executables.

- Provide a way to isolate vtk extensions from the main line vtk builds.

- Removes the need for some ifdef's in code, for example, an OpenGL factory
could replace all of the ifdef's in vtkRenderer and vtkRenderWindow.

- Debugging of New calls.  A factory can be created that does nothing, but
track the number of times New is called for each class type.

- Easier implementation of accelerated vtk objects on different hardware
using a plugin model much like netscape and photoshop have.


OBJECT FACTORY IMPLEMENTATION:

The object factory follows the Abstract Factory Design Pattern.  The root
class is called vtkObjectFactory.  vtkObjectFactory maintains a list of
"registered" factories.  It also contains a static class method used to
create vtk objects by string name.  The create method iterates over the
registered factories asking each one to create the object.  If a factory
returns an object, no other factories are asked to create the object.

Factories can be registered in two ways.  The first, at run time a program
can call vtkObjectFactory::RegisterFactory(new MyFactory).  The second way is
using dynamic loading and the environment variable VTK_AUTOLOAD_PATH.  The
first time the vtkObjectFactory is asked to create an object, it loads all
shared libraries or DLL's in the VTK_AUTOLOAD_PATH.  For each library the "C"
function vtkLoad is called to create an instance of vtkObjectFactory.  This
is only done the first time to avoid performance problems.  However, it is
possible to re-check the path for new factories at run time by calling
vtkObjectFactory::ReHash().


IMPACT ON VTK CLASSES:

- Every New method should ask the factory first.


Here is an example New method from vtkVertex:

//--------------------------------------------------------------------------
vtkVertex* vtkVertex::New()
{
// First try to create the object from the  vtkObjectFactory

   vtkObject* ret =   vtkObjectFactory::CreateInstance("vtkVertex");
   if(ret)
   {
     return (vtkVertex*)ret;
   }
  // If the factory was unable to create the object, then create it here.
   return new vtkVertex;
}


- Possible performance problems if New is called many times.  If this is
   seen, then that object can go back to the old New.  However, that object
   will then not be able to be overridden in by a factory.  Right now every
   class, but vtkDynamicLoader, and vtkDirectory use the object factory, as
   these classes are used in the dynamic load process.


HOW TO WRITE A FACTORY:

- The first thing you need to do is to create a sub-class
   of vtkObjectFactory.  You must implement the following virtual function in
   your factory:

  virtual vtkObject* CreateObject(const char* vtkclassname)

The function should return 0 if your factory does not want to handle the
class name it is being asked to create.  It should return a sub-class of the
named vtk class if it wants to override the class.  Since the CreateObject
method returns a vtkObject* there is not much type safety other than the
object must be a vtkObject, so be careful to only return sub-classes of the
object to avoid run time errors.

A factory can handle as many objects as it wants.  If many objects are to be
created, it would be best to use a hash table to map from the string names to
the object creation.  The method should be FAST.

HOW TO INSTALL A FACTORY:

- Compiled in factories need only call
  vtkObjectFactory::RegisterFactory ( MyFactory::New() )

- For dynamically loaded factories, a shared library or dll must be created
   which contains the object factory sub-class.  The library must have a
   single "C" linkage function called vtkLoad which returns an instance of the
   factory provided by the library.  An example vtkLoad looks like this:

   extern "C" vtkLoad() { return myObjectFactory::New(); }

- The library must then be put in the VTK_AUTOLOAD_PATH.  This variable
   follows the convention of PATH on your machine using ";" on windows, and
   ":" on Unix as a separator.


NEW VTK CLASSES The following classes have been added to common to support
object factories:

vtkObjectFactory, vtkDirectory, vtkDynamicLoader








-----------------------------------------------------------------------------
This is the private VTK discussion list.  Please keep messages on-topic.
Check the FAQ at: <http://www.automatrix.com/cgi-bin/vtkfaq>
To UNSUBSCRIBE, send message body containing "unsubscribe vtkusers" to
<majordomo at gsao.med.ge.com>.  For help, send message body containing
"info vtkusers" to the same address.     Live long and prosper.
-----------------------------------------------------------------------------

</x-flowed>



More information about the vtkusers mailing list