Design » Plugin architecture

Atlas’ concepts can be easily extended with custom implementations. Think e.g. custom Grids, Partitioners, MeshGenerators, FunctionSpaces, and many other abstract Atlas concepts. Rather than adding implementations in the Atlas library itself, the implementations may reside in Atlas “plugins”.

What?

An Atlas plugin is essentially a shared library constructed and installed in a specific manner that gets dynamically loaded at runtime of executables that make use of Atlas.

When the plugin library is loaded, it registers “ObjectBuilders” of concrete “Objects” implemented in the plugin in the Atlas “ObjectFactory”, as explained in Object oriented design.

Using a plugin

When Atlas is initialized at runtime, the environment variable ATLAS_PLUGINS is evaluated as a comma-separated lists of plugin names. The shared library corresponding to each plugin name will then be dynamically loaded.

Each plugin shared library will be found without further hints if it is installed in the same install prefix as Atlas itself. Otherwise further comma-separated hints can be supplied with the environment variable ATLAS_PLUGIN_SEARCH_PATHS

Creating a plugin

Assume the plugin we want to create has name “my-plugin-name”. The plugin’s CMakeLists.txt should then contain following:

find_package(atlas REQUIRED)

atlas_create_plugin( my-plugin-name )

The CMake macro atlas_create_plugin is exported from Atlas upon find_package( atlas ... ), and guarantees that the plugin will be recognized by Atlas.

Within the plugin source code, it is mandatory to create a class which inherits from Plugin

// file: MyPlugin.h

#include "atlas/library/Plugin.h"

namespace my_plugin {

class MyPlugin : public atlas::Plugin {
private:
    MyPlugin();
public:
    static const MyPlugin& instance();
    std::string version() const override;
    std::string gitsha1( unsigned int count ) const override;
};

} // namespace my_plugin
// file: MyPlugin.cc

#include "MyPlugin.h"

namespace my_plugin {

REGISTER_LIBRARY( MyPlugin ); // Self-registration

MyPlugin::MyPlugin() : atlas::Plugin( "my-plugin-name" ) {} // Name of the plugin

const MyPlugin& MyPlugin::instance() {
    static MyPlugin plugin;
    return plugin;
}

std::string MyPlugin::version() const {
    return "0.0.0"; // or replace with real version
}

std::string MyPlugin::gitsha1( unsigned int count ) const override {
    return "not available"; // or replace with real git sha1
}

} // namespace my_plugin

It is now possible to add classes to the plugin that extend Atlas classes, just as if this plugin was part of the Atlas main library.