How to create a Component

LCG Project | LCG Applications Area

SEAL Project | Project Portal

LCG Application Area Workbook

$Date: 2004/06/28 17:34:30 $

Overview

This guide explains how to create your own component, how to make it loadable through the plugin manager and how to use it in your application. These are the steps:

Define a SEAL component

You can create classes as components or services. Services are components, but in addition can be configured, via a property manager and initialized.
In order to create a component (service) you need to inherit from component (service).

Typical header file for a component looks like this:

#ifndef MYCOMPONENT_H
# define MYCOMPONENT_H

# include "SealKernel/Component.h"


class MyComponent : public seal::Component
{

DECLARE_SEAL_COMPONENT;

public:

MyComponent (seal::Context* context);
MyComponent (seal::Context* context, const std::string & label);

// implicit copy constructor
// implicit assignment operator
// implicit destructor

//.....component member functions..
void doSomething();

};



#endif // MYCOMPONENT_H

You need to insert the macro DECLARE_SEAL_COMPONENT,  to have your component decleared in your application, and you need to have constructors taking a seal::Context pointer and label as arguments.

The implementation file looks like this:


#include "MyComponent.h"
#include <iostream>


DEFINE_SEAL_COMPONENT (MyComponent, "seal/example/MyComponent");


MyComponent::MyComponent (seal::Context* context)
: Component (context, classContextKey ())
{}

MyComponent::MyComponent (seal::Context* context, const std::string & label)
: Component (context, label)
{}


// member function implementations

void MyComponent::doSomething() { std::cout << "MyComponent: Hello World ! " << std::endl; }

You need to use the macro DEFINE_SEAL_COMPONENT which takes as arguments the class and a unique string, which identifies the component and it is used by the plugin manager to load it. In the implementation of the constructor you register the component in the passed context, using the constructor of the base Component class. 

If you want to create a service, the only difference is that you need to have MyService inherithing from seal::Service.

How to make the component loadable

You can load the component dynamically in your application using the SEAL plugin manager.
To do that you need to create a module.cpp file which declares the component as a plugin. Here is an example of that file:

#include "MyComponent.h"
#include "SealKernel/ComponentFactory.h"
#include "PluginManager/ModuleDef.h"

DEFINE_SEAL_MODULE ();
DEFINE_SEAL_PLUGIN (seal::ComponentFactory, MyComponent,
                    MyComponent::classContextLabel ());

How to use the component

You can load the component dynamically using the plugin manager. You need to have an handle to the ComponentLoader and be in a context. The ComponentLoader handle can be retrieved from the top application (seal::Application). Here is a simple example  where  MyComponent is loaded in the top context and then used. 


#include "SealKernel/Application.h"
#include "SealKernel/ComponentLoader.h"
#include "MyComponent.h"

using namespace seal;
int main (int, char**)
{
// Initialise framework
Application theApp;

// Dynamically load services
Handle<ComponentLoader> loader = theApp.component<ComponentLoader>();
loader->load ("seal/example/MyComponent");

// get an handle of the component from the context

Context* topc = theApp.context();
Handle<MyComponent> handle = topc->component<MyComponent>();
handle->doSomething();

// to load again the component give an extra label to distinguish
loader->load ("seal/example/MyComponent","MyComponent_2");
Handle<MyComponent> handle_2 = topc->component<MyComponent>("MyComponent_2");
handle_2->doSomething();

return 0;
}