Charon-core is a library, so don't look for some kind of main executable.
You can use charon-core in your own projects, use the classes and frameworks that are offered here. A sample data-processing framework that uses the ParameteredObject class can be found in the imgmanip
directory. The file test/parametertest.cpp
and test/imgmaniptest.cpp
show how to use it.
Implementing a parametered Object
Here, we discuss the content of the source file paramObjSample.cpp
in the examples directory.
#include <iostream>
#include <cstdlib>
Obviously, the new class needs to inherit from
ParameteredObject to get all the features defined there.
Here we define the parameters that we want to use to store the object properties. These properties can be stored by
ParameteredObject::saveParameters(), which only saves the parameters and
ParameteredObject::save() which also stored the slot connections. The parameters can be loaded by
ParameteredObject::loadParameters(). Like
ParameteredObject::saveParameters(), this doesn't touch the slots. We also define input and output slots that can be used for data exchange between objects.
Sample(const std::string& name = "") :
par1(20),
par2(1.5),
out1(8),
out2(7.3f),
in2(true, true)
{
}
};
In the constructor, we have to call the inherited constructor of
ParameteredObject. There, we have to specify an unique class name and pass the instance name. Then we have to initialize the parameters and output slots. Input slot
in2 is initialized as optional multislot. The effects are described below. Within the constructor, we have to add all parameters and slots to the corresponding management lists. This is done by calls of the following functions:
This can also be delegated to some init() function if there are more than one constructor. The parameters of the _addXX functions are described in the API documentation.
public:
Outputgen(const std::string& name = "") :
"class to generate int and float output"),
out1(10),
out2(5.5f)
{
}
};
The second example class is declared similarly.
int main() {
Sample* sample = new Sample;
sample->par1 = 5;
sample->saveParameters(testfile);
sample->par1 = 10;
sample->loadParameters(testfile);
sout <<
"par1: " << sample->par1 << std::endl;
Object creation and access of the parameters is quite easy. The save/load routines handle all registered parameters.
Outputgen* outgen = new Outputgen;
Outputgen* outgen2 = new Outputgen;
outgen->out1.connect(sample->in1);
outgen->out2.connect(sample->in2);
outgen2->out2.connect(sample->in2);
Here you can see how objects can be connected with each other.
sample->save(testfile);
outgen->save(testfile);
outgen2->save(testfile);
The object connections are also saved by the
ParameteredObject::save() routine. The slot data will
not be stored.
delete sample;
assert(!outgen->out1.connected());
assert(!outgen->out2.connected());
delete outgen;
delete outgen2;
We do the cleanup and make sure that the destructor automatically disconnects existing slot connections.
testfile.
save(
"example.wrp");
return EXIT_SUCCESS;
}
At the end, we save the
ParameterFile to the disk.
Dynamic Modules
It is possible to write Modules where the number or kind of Parameters and Slots is not fix in any configuration. Such modules, where this parameter/slot interface depends on its configuration (i.e., in the most general case, it depends on the workflow configuration parameter file) are called dynamic Modules.
For writing such dynamic modules, you have to call the function ParameteredObject::_setDynamic() within the constructor to set up the module metadata such that other tools know, that the module interface has to be queried providing the current configuration.
The next step is to reimplement the virtual function ParameteredObject::prepareDynamicInterface(const ParameterFile&) where the current configuration is provided as a parameter file. Within this function, the information from the parameter file may be used to determine, which parameters and slots to set up. Definition/registration of these parameter/slots is done there as usual. Do not forget to call the following routines for registration:
Other tools and frameworks in charon-core
The most important framework in charon-core is the ParameteredObject framework mentioned above. But there are even more nice features. These features are easy to understand so the API documentation should be sufficient:
- class FileTool:
platform independent file manipulations
- class ParameterFile:
parameter file handling used by parametered objects etc.
- class SplitStream:
highly customizable output stream class with possibility to stream into different targets etc.
- class StringTool:
string manipulations
- class TypeDetector:
guessing of basic data types