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
Last revision Both sides next revision
wiki:documentation:devguide:core:plugins [2016/11/21 10:05]
carolina.santos
wiki:documentation:devguide:core:plugins [2016/11/21 10:38]
carolina.santos
Line 17: Line 17:
   * 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 **CppPluginEngine** class inherits 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 76: Line 79:
 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 260: Line 264:
 </​code>​ </​code>​
  
-The **PluginInfo** class has attributes to model the basic information 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.   * ''​name'':​ an unique internal value used to identify the plugin in the system.
Line 282: Line 286:
       * ''​version'':​ system version.       * ''​version'':​ system version.
  
-This class is an object that is serialized from JSON files, as shown below:+===== Examples ===== 
 + 
 +Here is a simple example using the functions provided by the **Plugins** classes:
  
 +plugin1.teplg.json:​
 <code cpp> <code cpp>
 { {
Line 311: Line 318:
 </​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 =====