TerraLib and TerraView Wiki Page

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
wiki:documentation:devguide:core:plugins [2016/11/21 10:04]
carolina.santos
wiki:documentation:devguide:core:plugins [2016/11/21 10:45] (current)
carolina.santos [C++]
Line 15: Line 15:
   * AbstractPlugin   * AbstractPlugin
   * AbstractPluginEngine   * AbstractPluginEngine
 +  * CppPlugin
 +  * CppPluginProxy
   * CppPluginEngine   * CppPluginEngine
   * PluginEngineManager   * PluginEngineManager
-  * PluginInfo 
   * PluginManager   * PluginManager
 +  * PluginInfo
  
 The **AbstractPlugin** class defines the interface of a plugin. Each programming language should provide a specific concrete class, which will be able to handle the details of the plugins built in that language. The C++ plugins must be created from the **CppPlugin** class specialization. Objects of this class will be handled by the TerraLib framework through a proxy, the **CppPluginProxy** class. This class (CppPluginProxy) helps to separate the actual plugin object from the manipulation of the shared library where the plugin is defined. This separation is important in the process of downloading the plugin from memory. The **AbstractPlugin** class defines the interface of a plugin. Each programming language should provide a specific concrete class, which will be able to handle the details of the plugins built in that language. The C++ plugins must be created from the **CppPlugin** class specialization. Objects of this class will be handled by the TerraLib framework through a proxy, the **CppPluginProxy** class. This class (CppPluginProxy) helps to separate the actual plugin object from the manipulation of the shared library where the plugin is defined. This separation is important in the process of downloading the plugin from memory.
  
-The **AbstractPluginEngine** class defines the interface of objects capable of performing the creation and loading of plugins from a set of information defined by a **PluginInfo** structure. Each programming language or structuring form of a plugin should provide a specific implementation of this class. This class eases how to prepare the load environment of a plugin. The **CppPluginEngine** class is capable of loading dynamic libraries that have an entry point defined by the ''​TERRALIB_PLUGIN_CALL_BACK_IMPL''​ macro.+The **AbstractPluginEngine** class defines the interface of objects capable of performing the creation and loading of plugins from a set of information defined by a **PluginInfo** structure. Each programming language or structuring form of a plugin should provide a specific implementation of this class. This class eases how to prepare the load environment of a plugin. 
 + 
 +The **PluginInfo** class is an object that is serialized from a JSON file and has attributes to model the basic information of a plugin, shown below: 
 + 
 +  * ''​name'':​ an unique internal value used to identify the plugin in the system. 
 +  * ''​display_name'':​ name to be displayed in the graphical interface. 
 +  * ''​description'':​ brief description of the plugin. 
 +  * ''​version'':​ plugin version. 
 +  * ''​release'':​ the launch date of the plugin. 
 +  * ''​engine'':​ the plugin engine type (C++, LUA, JAVA). 
 +  * ''​license_description'':​ a brief description of the plugin license. 
 +  * ''​license_URL'':​ an URL where you can find more information about the license. 
 +  * ''​site'':​ an URL pointing to the plugin'​s website. 
 +  * ''​provider'':​ information about the plugin developer. 
 +      * ''​name'':​ provider name. 
 +      * ''​site'':​ provider website. 
 +      * ''​email'':​ provider email. 
 +  * ''​dependencies'':​ a list of plugins required for the plugin to be used. 
 +  * ''​linked_libraries'':​ a list of linked libraries. 
 +  * ''​resources'':​ a list of features used by the plugin. 
 +  * ''​host_application'':​ host system information. 
 +      * ''​name'':​ system name. 
 +      * ''​version'':​ system version. 
 + 
 +The **CppPluginEngine** class derives from the **AbstractPluginEngine** class and is capable of loading dynamic libraries that have an entry point defined by the ''​TERRALIB_PLUGIN_CALL_BACK_IMPL''​ macro.
  
 +**CppPluginEngine** class:
 <code cpp> <code cpp>
 namespace te namespace te
Line 35: Line 62:
       \brief A plugin engine for plugins written in C++.       \brief A plugin engine for plugins written in C++.
      */      */
-    class TECOREEXPORT ​CppPluginEngine : public AbstractPluginEngine+    class CppPluginEngine : public AbstractPluginEngine
     {     {
       public:       public:
Line 65: Line 92:
          */          */
         void unload(std::​unique_ptr<​AbstractPlugin>​ plugin);         void unload(std::​unique_ptr<​AbstractPlugin>​ plugin);
- +        ​
-      private: +
- +
-        struct Impl; +
- +
-        Impl* m_pimpl;+
     };     };
  
Line 77: Line 99:
 </​code>​ </​code>​
  
-The **PluginEngineManager** class is a singleton that will contain the record of all types of plugin loaders available in the system. The developer of new plugin loaders, classes derived from **AbstractPluginEngine**,​ should register objects in this singleton so TerraLib-based applications can load plugins.+The **PluginEngineManager** class is a singleton that will contain the record of all types of plugin loaders available in the system. The developer of new plugin loaders, classes derived from **AbstractPluginEngine**,​ should register objects in this singleton so TerraLib-based applications can load the plugins.
  
 The **PluginManager** class is a singleton that will manage the registration of all the plugins, allowing the loading, downloading,​ initialization and finalization of the plugins. The **PluginManager** class is a singleton that will manage the registration of all the plugins, allowing the loading, downloading,​ initialization and finalization of the plugins.
  
 +**PluginManager** class:
 <code cpp> <code cpp>
 namespace te namespace te
Line 265: Line 288:
 </​code>​ </​code>​
  
-The **PluginInfo** class has attributes to model the basic information of a plugin:+===== Examples =====
  
-  * ''​name'':​ an unique internal value used to identify the plugin in the system. +Here is simple example using the functions provided by the **Plugins** classes:
-  * ''​display_name'':​ name to be displayed in the graphical interface. +
-  * ''​description'':​ brief description of the plugin. +
-  * ''​version'':​ plugin version. +
-  * ''​release'':​ the launch date of the plugin. +
-  * ''​engine'':​ the plugin engine type (C++, LUA, JAVA). +
-  * ''​license_description'': ​brief description of the plugin license. +
-  * ''​license_URL'':​ an URL where you can find more information about the license. +
-  ​''​site'':​ an URL pointing to the plugin'​s website. +
-  ​''​provider'':​ information about the plugin developer. +
-      ​''​name'':​ provider name. +
-      ​''​site'':​ provider website. +
-      * ''​email'':​ provider email. +
-  * ''​dependencies'':​ a list of plugins required for the plugin to be used. +
-  * ''​linked_libraries'':​ a list of linked libraries. +
-  * ''​resources'':​ a list of features used by the plugin. +
-  * ''​host_application'':​ host system information. +
-      * ''​name'':​ system name. +
-      * ''​version'':​ system version. +
- +
-This class is an object that is serialized from JSON files, as shown below:+
  
 +plugin1.teplg.json:​
 <code cpp> <code cpp>
 { {
Line 316: Line 320:
 </​code>​ </​code>​
  
-===== Examples =====+Plugin1.cpp:​
  
 +<code cpp>
 +/// TerraLib
 +#include <​terralib/​core/​plugin/​CppPlugin.h>​
  
 +// STL
 +#include <​iostream>​
 +
 +TERRALIB_CPP_PLUGIN_BEGIN(Plugin1)
 +
 +TERRALIB_CPP_PLUGIN_STARTUP
 +{
 +  if(m_initialized)
 +    return;
 +  ​
 +  std::cout << "​Plugin1 startup"​ << std::endl;
 +  ​
 +  m_initialized = true;
 +}
 +
 +TERRALIB_CPP_PLUGIN_SHUTDOWN
 +{
 +  std::cout << "​Plugin1 shutdown"​ << std::endl;
 +  ​
 +  m_initialized = false;
 +}
 +
 +TERRALIB_CPP_PLUGIN_END(Plugin1)
 +</​code>​
 +
 +main.cpp:
 +
 +<code cpp>
 +// TerraLib
 +#include <​terralib/​core/​plugin.h>​
 +#include <​terralib/​core/​utils.h>​
 +
 +// STL
 +#include <​cstdlib>​
 +#include <​iostream>​
 +
 +void WithoutPluginManager()
 +{
 +  // plugins will be loaded with C++ plugin engine
 +  te::​core::​AbstractPluginEngine&​ plugin_engine =
 +      te::​core::​PluginEngineManager::​instance().get("​C++"​);​
 +
 +  // find fisrt plugin manifest file, read the manifest, load plugin and start
 +  // it
 +  std::string p1_manifest_file =
 +      te::​core::​FindInTerraLibPath("​example/​plugins/​plugin1.teplg.json"​);​
 +
 +  te::​core::​PluginInfo p1_info =
 +      te::​core::​JSONPluginInfoSerializer(p1_manifest_file);​
 +
 +  std::​unique_ptr<​te::​core::​AbstractPlugin>​ p1(plugin_engine.load(p1_info));​
 +
 +  p1->​startup();​
 +
 +  // find second plugin manifest file, read the manifest, load plugin and start
 +  // it
 +  std::string p3_manifest_file =
 +      te::​core::​FindInTerraLibPath("​example/​plugins/​plugin3.teplg.json"​);​
 +
 +  te::​core::​PluginInfo p3_info =
 +      te::​core::​JSONPluginInfoSerializer(p3_manifest_file);​
 +
 +  std::​unique_ptr<​te::​core::​AbstractPlugin>​ p3(plugin_engine.load(p3_info));​
 +
 +  p3->​startup();​
 +
 +  // stop all plugins and unload them
 +  p3->​shutdown();​
 +  plugin_engine.unload(std::​move(p3));​
 +
 +  p1->​shutdown();​
 +  plugin_engine.unload(std::​move(p1));​
 +}
 +
 +void WithPluginManager()
 +{
 +  // Load all the config files for the plugins.
 +  std::​vector<​te::​core::​PluginInfo>​ v_pInfo;
 +
 +  v_pInfo.push_back(te::​core::​JSONPluginInfoSerializer(
 +      te::​core::​FindInTerraLibPath("​example/​plugins/​plugin1.teplg.json"​)));​
 +  v_pInfo.push_back(te::​core::​JSONPluginInfoSerializer(
 +      te::​core::​FindInTerraLibPath("​example/​plugins/​plugin2.teplg.json"​)));​
 +  v_pInfo.push_back(te::​core::​JSONPluginInfoSerializer(
 +      te::​core::​FindInTerraLibPath("​example/​plugins/​plugin3.teplg.json"​)));​
 +  v_pInfo.push_back(te::​core::​JSONPluginInfoSerializer(
 +      te::​core::​FindInTerraLibPath("​example/​plugins/​plugin4.teplg.json"​)));​
 +
 +  // Insert all the plugins stored in the vector from a given PluginInfo.
 +  v_pInfo = te::​core::​plugin::​TopologicalSort(v_pInfo);​
 +
 +  for(const te::​core::​PluginInfo&​ pinfo : v_pInfo)
 +  {
 +    te::​core::​PluginManager::​instance().insert(pinfo);​
 +    te::​core::​PluginManager::​instance().load(pinfo.name);​
 +  }
 +
 +  // get all the loaded plugins
 +  std::​vector<​te::​core::​PluginInfo>​ pVec =
 +      te::​core::​PluginManager::​instance().getLoadedPlugins();​
 +
 +  // unload it in the reverse order
 +  for (auto plugin = pVec.rbegin();​ plugin != pVec.rend();​ ++plugin)
 +  {
 +    te::​core::​PluginManager::​instance().stop(plugin->​name);​
 +    te::​core::​PluginManager::​instance().unload(plugin->​name);​
 +  }
 +  te::​core::​PluginManager::​instance().clear();​
 +}
 +
 +int main(int argc, char* argv[])
 +{
 +  try
 +  {
 +    te::​core::​plugin::​InitializePluginSystem();​
 +    WithoutPluginManager();​
 +    WithPluginManager();​
 +    te::​core::​plugin::​FinalizePluginSystem();​
 +  }
 +  catch(boost::​exception&​ e)
 +  {
 +    std::​string* err = boost::​get_error_info<​te::​ErrorDescription>​(e);​
 +    std::cerr << *err << std::endl;
 +  }
 +
 +  return EXIT_SUCCESS;​
 +}
 +</​code>​
  
 ===== Additional References ===== ===== Additional References =====