plugin.h File Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

Classes | Namespaces | Defines | Functions
plugin.h File Reference
Plugins
`#include <openbabel/babelconfig.h>`
`#include <string>`
`#include <iostream>`
`#include <vector>`
`#include <map>`
`#include <sstream>`
`#include <cstring>`
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

## Classes
struct | CharPtrLess
| Case insensitive string comparison for PluginMapType key. More...
class | OBPlugin
| Base class for all types of dynamic classes discovered at runtime. More...
## Namespaces
namespace | OpenBabel
## Defines
#define | MAKE_PLUGIN(BaseClass)
#define | OB_STATIC_PLUGIN(className, instanceName)
## Functions
std::vector< std::string > | EnableStaticPlugins ()

## Detailed Description

Simplify 'plugin' classes to be discovered and/or loaded at runtime.

The code in this file makes it easy to make 'plugin' classes. These classes are derived from a base class, like OBFingerprint. The derived classes ('sub-types' like fingerprint2) usually have a single instance. Plugin classes are only discovered at runtime, so no existing code needs to be changed when adding a new derived class. In some builds the new code can be added or removed by just moving a DLL or so file. The plugin classes derived from any base class (including new ones) type can be listed from the commandline.

## Step-by-Step Instructions

1) In the header file for YourBaseClass (which handles whatsits). Make sure to include the plugin.h header , derive the class from OBPlugin and in its definition add the MAKE_PLUGIN macro and a function TypeID() containing a simple descriptor of the type

    #include <openbabel/plugin.h>
    class YourBaseClass : public OBPlugin
    {
      MAKE_PLUGIN(YourBaseClass)

      const char* TypeID()
      { return "whatsits"; };

      ...rest of implementation, probably involving virtual functions redefined
      in the sub-type classes
    };

See below for what the macro contains.

2) Declare each sub-type in a class derived from the base class and give it a constructor which calls OBPlugin constructor as shown:

    class YourSubType1 : public YourBaseClass
    {
    public:
      YourSubtype1(const char* ID, bool IsDefault=false)
        : YourBaseClass(ID, IsDefault){}

      virtual string Description()
      { return "A description with one or more lines";};

      ...rest of implementation
    };

Only the first line of the description is used when the subclasses are listed.

3) Declare a global instance of the sub-type class which specifies its ID. and, optionally, whether it is to be regarded as the default type of YourBaseClass.

    YourSubType1 theType1("whatsit2",true);

4) The following functions are available:

YourBaseClass* YourBaseClass::FindType(const char* ID); This returns the default type when ID is NULL or empty.

To list the sub-types of any plugin class use the List which sends to cout by default (or any other ostream if specified).

      OBPlugin::List("whatsits")

The ListAsString and ListAsVector functions are alternatives, usable with scripting.

It is also possible to iterate through each sub-type by the following code:

      OBPlugin::PluginIterator itr;
      for(itr=OBPlugin::Begin("whatsits");itr!=OBPlugin::End("whatsits");++itr)
      {
        itr is a std::map::const_iterator
        itr->first is the ID of the subtype;
        itr->second is The OBPlugin* which you will have to cast to your type
      }

Since this is not the most beautiful code, it is probably better to use the List methods if possible.

YourBaseClass* MakeNewInstance();

## How it works

MAKE_PLUGIN(YourBaseClass) inserts the following code into YourBaseClass:

    protected:

      //The collection of sub-types is in a local static variable to avoid
      //any difficulties with the order of initialization of static objects.
      static PluginMapType& Map()
      {
        static PluginMapType m;
        return m;
      }

      //Making the map accessible to the base class (Cannot be used during construction)
      virtual PluginMapType& GetMap()const
      {
       return Map();
      }

    public:
      static YourBaseClass*& Default()
      {
        static YourBaseClass* d;
        return d;
      }

      //Constructor registers the sub-type
      YourBaseClass(const char* ID, bool IsDefault=false)
      {
        _id = ID;
        if(ID && *ID && *ID!=' ') //do not register if ID is empty or starts with a space
        {
          if(IsDefault || Map().empty())
            Default() = this;
          Map()[ID]=this;
          //Ensure YourBaseClass is registered in OBPlugin so it can be accessed from the commandline
          PluginMap()[TypeID()] =this;
        }
      }

      static YourBaseClass* FindType(const char* ID)
      {
        if(!ID || *ID==0)
          return Default();
        return static_cast<YourBaseClass*>(BaseFindType(Map(),ID));
      }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines