Derived class discovery at compile time¶
The RuntimeSelectionFactory
class is a template class that allows to register derived classes for creation at runtime via a factory class by its name.
The classes are registered at compile time via static member initialization.
Additional explanation can be found in the following two posts on Stack OverFlow: Derived class discovery at compile time and How to automatically register a class on creation .
This approach allows to create a plugin architecture where a derived class can be loaded at runtime. Additionally, it simplifies the runtime selection of a specific class. The derived classes can be created by providing its name, as shown below:
std::unique_ptr<baseClass> derivedClass =
baseClass::create("Name of derivedClass", "Additional arguments",...);
The RuntimeSelectionFactory
class is a template class that manages the registration of the derived classes and stores the map of the registered classes.
The map associates a function with a string that is used to create the derived class.
Further details RuntimeSelectionFactory.
Usage¶
The following example shows how to use the RuntimeSelectionFactory
and RuntimeSelectionFactory::Register
to automatically register derived classes. (check registerClass.cpp
for details).
The static function create
returns a std::unique_ptr
to its base class and takes an argument list specified inside the template class NeoN::Parameters<>
.
template<typename Base, typename... Args>
class RuntimeSelectionFactory<Base, Parameters<Args...>> : public RegisterDocumentation<Base>
{
static std::unique_ptr<Base> create(const std::string& key, Args... args)
{
keyExistsOrError(key);
auto ptr = table().at(key)(std::forward<Args>(args)...);
return ptr;
}
};
To register a class, derive from the BaseClass::Register class and pass the derived class as a template argument.
The derived class must implement the static functions name
, doc
, and schema
.
class DerivedClass : public BaseClass::Register<DerivedClass>
{
public:
DerivedClass() {}
static std::string name() { return "DerivedClass"; }
static std::string doc() { return "DerivedClass documentation"; }
static std::string schema() { return "DerivedClass schema"; }
};
After the classes have been defined, the create
function can be used to instantiate the derived classes based on the name provided.
std::unique_ptr<BaseClass> testDerived = BaseClass::create("DerivedClass");
All base classes are also registered in the NeoN::BaseClassDocumentation
map and the documentation and the schema retrieved as followed:
std::string baseClassName = "BaseClass";
std::string derivedClass = "DerivedClass";
NeoN::BaseClassDocumentation::doc(baseClassName, derivedClass)
NeoN::BaseClassDocumentation::schema(baseClassName, derivedClass)
This mechanism should simplify the creation of tooling around NeoN