![]() |
User Manual, Developers Guide and API Documentation |
![]() |
By convention, every StaticFactory template instance is typedefed for your convenience. Assume a collection of plugins that all conform to a given interface, say TestInterface:
struct TestInterface { // this is a base class... virtual ~TestInterface() {} // some state... long foo; // some behaviour... virtual void set(long) = 0; };
Then there are two more types declared to work with:
// assert, that the plugin with name "plugin 1" has been registered ASSERT( TestFactory::knows("plugin 1") ); // to create instances of a plugin, we first need to query // the factory for a creator. TestCreator* c = TestFactory::creator("plugin 1"); // once having such a creator, we can create any number of // plugins using the creator's create method. TestInterface* p1 = c->create(); // assure that the constructor of the plugin has been called and // set the attribute foo. ASSERT( p1->foo == 666 ); // we can call anything the interface provides... p1->set(23); ASSERT( p1->foo == 23 ); delete p1;
Each StaticFactory defines its interface as an abstract class. For example the StaticFactory 'TestFactory' could define a class 'TestInterface'. To write your own plugin, you simply have to write a realisation of the interface and register your plugin at the StaticFactory:
class Plugin1 : public TestInterface { public: Plugin1() { foo = 666; } virtual void set(long i) { foo = i; } }; STATIC_FACTORY_REGISTER(Plugin1, TestInterface, "plugin 1");
Things get only slightly more difficult, if you want to provide a plugin for a StaticFactory that requests a constructor with another signature. As you saw, plugin instances are created using a creator. For different constructor signatures, you need different creators. Creators are named loosely after their signature by convention. For example LongCreator for interfaces that require the constructor to have one argument of type long, LayerConfigCreator for constructors with the signature (ILayer*, pyconfig::View*).
Assuming a FunkFactory, that requires its plugin implementations to have a constructor with a long as single argument, an implementation could look like:
class Hancock : public FunkInterface { public: Hancock(long _l) : FunkInterface(_l) { l = _l; } long getIt() { return l; } private: long l; }; STATIC_FACTORY_REGISTER_WITH_CREATOR(Hancock, FunkInterface, "Hancock", LongCreator);
struct TestInterface { // this is a base class... virtual ~TestInterface() {} // some state... long foo; // some behaviour... virtual void set(long) = 0; };
Second you have to choose a creator. If you are lucky, a creator with the desired constructor signature already exists. If not, have a look at LongCreator.hpp or LayerConfigCreator.hpp for examples.
The only thing left to do is to provide some typedefs for convenience:
typedef Creator<TestInterface> TestCreator; typedef StaticFactory<TestCreator> TestFactory;
If you chose to use a different creator than the default creator Creator, you have to use that instead. Have a look at the complete FunkInterface components for an example of how to create a factory with a different creator:
struct FunkInterface { FunkInterface(long) {} virtual ~FunkInterface() {} virtual long getIt() = 0; }; typedef LongCreator<FunkInterface> FunkCreator; typedef StaticFactory<FunkCreator> FunkFactory;
1.5.5