Registering your plug-in

Opticks discovers your plug-ins by loading your plug-in library and then querying for any registered plug-ins.

If you haven't created a plug-in subclass to register, please read Create Plug-In Class . Once you have a plug-in subclass to register, you will first need to prepare your plug-in library (i.e. .dll, .so) by registering a module inside your library.

In order to register a module inside your library, it is recommended that you create a new .cpp file called ModuleManager.cpp. Inside this ModuleManager.cpp, you should use the REGISTER_MODULE() macro. Below, you will see the ModuleManager.cpp that is included with the Tutorial plug-in library.

/*
 * The information in this file is
 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
 * and is subject to the terms and conditions of the
 * GNU Lesser General Public License Version 2.1
 * The license text is available from   
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "PlugInRegistration.h"

REGISTER_MODULE(OpticksTutorial);

The REGISTER_MODULE() macro has one argument, which is the module ID. This module ID must be a valid C++ identifier and must not be used elsewhere in your plug-in library. The module ID will be used to declare a C++ namespace inside your plug-in library and must therefore be unique. In addition, this module ID must be unique for all other plug-in libraries that might be loaded by the application. If two plug-in libraries have the same module ID, only the first will be loaded by the application. In addition, you must only use the REGISTER_MODULE() macro once in your plug-in library. Attempting to use it twice inside a single plug-in library will cause compile and link errors.

Now that your plug-in library has a registered module, you can actually register your individual plug-in subclasses.

You can use one of two macros to register your individual plug-in subclasses. You can use either REGISTER_PLUGIN() or REGISTER_PLUGIN_BASIC(), see below for examples.

REGISTER_PLUGIN(OpticksTutorial, Tutorial1, Tutorial1);
or
REGISTER_PLUGIN_BASIC(OpticksTutorial, Tutorial1);
The first argument to either macro is the module ID that was used in the REGISTER_MODULE() macro. The last argument to either macro is the constructor of your plug-in subclass. The REGISTER_PLUGIN() macro uses its second argument to uniquely identify the plug-in within the module. If your plug-in subclass is not templated and has a no-argument constructor, you can simply use the REGISTER_PLUGIN_BASIC() macro which will deduce the plug-in identifier from the plug-ins classname. If however, your plug-in subclass requires constructor arguments or is templated, you should instead use REGISTER_PLUGIN() and provide a unique identifier for plug-in as the second argument to the macro. The plug-in identifier provided must be a valid C++ identifier and needs only to be unique within the context of the module. Please see below for a more complete example.
//assume there are two plug-in subclasses, that would constructed as follows:
// PlugIn* pPlugIn1 = new TestPlugIn();
// PlugIn* pPlugIn2 = new TestPlugIn2<int>(true);
//see below for the plug-in registration code:
REGISTER_MODULE(TestModule);

REGISTER_PLUGIN_BASIC(TestModule, TestPlugIn); //one could also use the commented out line below
//REGISTER_PLUGIN(TestModule, TestPlugIn, TestPlugIn);

//REGISTER_PLUGIN_BASIC(TestModule, TestPlugIn2<int>(true)); //this will NOT compile, instead use the line below
REGISTER_PLUGIN(TestModule, TestPlugIn2, TestPlugIn2<int>(true));

When using REGISTER_MODULE(), REGISTER_PLUGIN() and REGISTER_PLUGIN_BASIC(), it's important to know that they can be put into any .cpp file that will included in your plug-in library (.dll, .so). This allows a developer to put the REGISTER_PLUGIN-* macro in the .cpp that is providing the implementation for that plug-in subclass. This completes the discussion on standard plug-in registration. If you'd like to learn more about a very advanced type of plug-in registration, you can continue reading the next section.

Advanced Plug-In Registration

The above documentation has described how to do static (i.e. compile-time) plug-in registration. It is also possible to perform plug-in registration during Opticks start-up the first time that Opticks loads a plug-in library (.dll, .so). This is known as dynamic plug-in registration. It is possible to mix both static and dynamic plug-in registration together in a single module.

In order to perform dynamic plug-in registration, you must first create a subclass of the DynamicPlugInFactory base class. It is this class that will perform all of the dynamic plug-in registration. You must then use the REGISTER_DYNAMIC_MODULE() macro instead of the REGISTER_MODULE() macro. Please keep in mind that you can still only use one use of this macro per plug-in library (.dll, .so). The REGISTER_DYNAMIC_MODULE() macro has a second argument that must be the name of the DynamicPlugInFactory subclass you have created. See below for an example.

/*
 * The information in this file is
 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
 * and is subject to the terms and conditions of the
 * GNU Lesser General Public License Version 2.1
 * The license text is available from   
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "CustomMenuPlugIn.h"
#include "FileFinder.h"
#include "Filename.h"
#include "ObjectResource.h"
#include "PlugInRegistration.h"

class CustomMenuPlugInFactory : public DynamicPlugInFactory
{
public:
   void init(bool locate, std::vector<std::string>& dynamicPlugIns)
   {      
      Service<ConfigurationSettings> pSettings;
      std::string searchPath = pSettings->getPlugInPath();
      
      FactoryResource<FileFinder> pFinder;
      pFinder->findFile(searchPath, "*.customplugin", false);
      
      bool foundPlugIn = pFinder->findNextFile();
      std::string plugIn;
      foundPlugIn = foundPlugIn && pFinder->getFileTitle(plugIn);
      while (foundPlugIn)
      {
         std::string fullPath;
         pFinder->getFullPath(fullPath);
         mPlugIns[plugIn] = fullPath;
         if (locate)
         {
            dynamicPlugIns.push_back(plugIn);
         }
         foundPlugIn = pFinder->findNextFile();
         foundPlugIn = foundPlugIn && pFinder->getFileTitle(plugIn);
      }
   }
   PlugIn* createPlugIn(const std::string& name)
   {
      if (mPlugIns.find(name) != mPlugIns.end())
      {
         return new CustomMenuPlugIn(name, mPlugIns[name]);
      }
      return NULL;
   }
   virtual ~CustomMenuPlugInFactory() {};
private:
   std::map<std::string, std::string> mPlugIns;
};

REGISTER_DYNAMIC_MODULE(OpticksPlugInSampler, CustomMenuPlugInFactory);
The source code above comes from the PlugInSampler. You can read Building and Running Tutorial plug-ins for information on building and running the above code. It is also suggested you read the documentation for DynamicPlugInFactory.

Software Development Kit - Opticks 4.9.1 Build 16498