The libFAUDES run-time interface (RTI) facilitates the development of applications that are transparent to libFAUDES extensions, e.g., the libFAUDES version of the Lua interpreter luafaudes and the graphical user interface DESTool.
The run-time interface provides a TypeRegistry for the application to instantiate objects by specifying their type as a std::string. The TypeRegistry is accompanied by the FunctionRegistry for the application to execute functions by their name. Thus, a libFAUDES application can query both registries and provide the supported types and functions to the user. The libFAUDES user-reference is set up by the build system to represent the contents of both registries.
The run-time interface is implemented by the following components:
Classes that participate in the run-time interface are referred to as faudes-types, instances are so called faudes-objects. Any faudes-type must be derived from the base class faudes::Type. A faudes-type inherits the convenience interface for token IO from Type, and, most relevent for the run-time interface, the factory function New(): each faudes-types must reimplement New() to allocate a new object of their respective type on heap. For a fully functional faudes-type, also an appropriate assignment operator and a copy constructor are required.
A faudes-type is accompanied by an instance of faudes::TypeDefinition. It holds a name (std::string) to identify the faudes-type, documentation (short text and html reference), and one faudes-object of the respective faudes-type. The latter is referred to as the prototype object and its New() method is used to construct new faudes-objects of the respective faudes-type. Thus, given a TypeDefinition, one can instantiate a corresponding faudes-object. To setup a TypeDefinition, you are meant to provide the faudes-type name, the protototype and a file from which to read the documentation.
Functions that participate in the run-time interface are organized similar to faudes-types. There is a base class faudes::Function from which to derive particular faudes-functions. The base class provides an interface to set function parameter values and to actually execute the function on the parameters. To derive a class from Function, you must reimplement the methods New(), DoTypeCheck(), and DoExecute(). The DoTypeCheck method is supposed to use a dynamic cast to initialize typed references to the function parameters. The DoExecute method then executes the function, typically by invoking a function via its C++ API. Each Function class is accompanied by a faudes::FunctionDefinition instance which holds a prototype, basic documentation and a list of valid signatures. Each signature represents a valid parameter type configurations in terms of faudes-types.
The faudes::TypeRegistry and the faudes::FunctionRegistry are containers for TypeDefinition and FunctionDefinition instances, respectively. Applications access the registries via faudes-type names and faudes-function names, see e.g. the global functions NewObject() and NewFunction(). There is also in interface to iterate through the regsitries and to test for the existence of an entry. However, while both registries inherit the std token-io interface, neither registry can be fully configured by reading from file. This is because each entry requires not only data (documentation, signature, etc) but also a prototype instance. The std C++ run-time type information (RTTI) does not provide a mechanism to instantiate an object of a class that is specified at runtime. Thus, each protototype must be defined at compiletime. The global function LoadRegistry() is automatically set-up by the build system to gather all relevant prototypes, insert them in the registries and to subsequently read further documentation from a configuration file.
Code generation should work for all types and functions with documentation entry "CType()" specified. Since there is only one CType() entry, all signatures of a function must be implemented by a single c-function. The generated code is placed at "./include/rtiautoload.*". The build system also provides support to merge the configuration "libfaudes.rti" file from various sources, incl. plugins.
To have your C++ class participate in the libFAUDES run-time interface:
You will need to inspect and edit the main Makefile or your plugin's Makefile to advertise your additional sources. A
To have your C++ function participate in the libFAUDES run-time interface:
Query function name.
Convenience function to access registry singleton.