-
Notifications
You must be signed in to change notification settings - Fork 0
/
Processings_with_configuration.mw
115 lines (86 loc) · 5.22 KB
/
Processings_with_configuration.mw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
TODO: This howto is work-in-progress.
If you have a processing object and you want it to behave differently given some configuration parameters, you should provide a configuration object containing such parameters and implement the configuration method to respond to parameter setting.
== Defining a configuration object ==
Configuration objects in CLAM must be a special kind of object called DynamicType. DynamicTypes provide, among other things, '''automatic interface generation''' to edit their properties on the NetworkEditor and '''XML serialization''' to dump store and restore configuration as part of the clamnetwork XML file.
This is an example of configuration object definition:
TODO: Paste a simple example here
class MyProcessingConfig:public CLAM::ProcessingConfig
{
DYNAMIC_TYPE_USING_INTERFACE( SimpleConfig, 1, ProcessingConfig );
DYN_ATTRIBUTE( 0, public, int, FrameSize);
protected:
void DefaultInit()
{
AddAll();
UpdateData();
SetFrameSize(512);
};
};
The DefaultInit method is where default attributes are added and initialized with a value. This is automatically called from the constructor.
'''Troubleshooting:''' If the plugin is not loading in NetworkEditor, check that "''DefaultInit()''" is defined (versus only declared: ''DefaultInit();'')
Once stored in XML format from the Network Editor, the Processing object that has this kind of configuration will read like this:
<processing id="SimpleProcessing_0" type="SimpleProcessing">
<FrameSize>1024</FrameSize>
</processing>
And the automatically derived configuration widget will look like this:
[[Image:SimpleConfigDialog.png|Splash screen]]
== Using your configuration object in the processing ==
* Define a inner type alias MyProcessing::Config for your configuration
* Add an 'Config mConfig' attribute to the class
* Implement the GetConfig method to return such object
* Implement the ConcreteConfigure method to be called every time it is provided a new configuration.
* In such a method, firstly use the CopyAsConcreteConfig method to copy the object
class MyProcessing : public CLAM::Processing
{
...
public:
typedef MyProcessingConfig Config;
...
public:
const CLAM::ProcessingConfig & GetConfig() const
{
return mConfig;
}
protected:
bool ConcreteConfigure(const CLAM::ProcessingConfig & config)
{
CopyAsConcreteConfig(mConfig, config);
// Use here the config to setup you object
return true; // Configuration ok
}
...
private:
Config mConfig;
};
== Reporting configuration errors ==
The configuration object may contain errors. In such case the ConcreteConfigure implementation should take two actions:
* Explaining the user the error by appending a message with the Processing::AddConfigErrorMessage method
* Returning false so that CLAM knows the configuration failed.
bool ConcreteConfigure(const CLAM::ProcessingConfig & config)
{
...
if (SomeWeirdConditionHappens)
{
AddConfigErrorMessage("Some weird condition");
return false;
}
...
Returning false will keep your processing in Unconfigured state (it can not be started).
It will also turn in red the processing when displayed by the NetworkEditor.
The message can be seen when you hover over the red processing.
Here we can see an example:
[[Image:NetTutorial-ErrorTooltip.png|center|A badly configured processing in the NetworkEditor]]
== Useful attribute types for configuration objects ==
* '''[http://clam.iua.upf.edu/doc/CLAM-devel-doxygen/classCLAM_1_1Text.html CLAM::Text]:''' It shares interface with std::string but Text supports spaces. std::string fails to read strings with spaces, it just takes the first word. Dont't use 'char*' as attribute type in any case.
* '''[http://clam.iua.upf.edu/doc/CLAM-devel-doxygen/classCLAM_1_1Enum.html CLAM::Enum]:''' Their runtime representation is numerical like C enums but they have string representation on XML and you can query available text values so the configuration dialog can retrieve the available values on a combobox.
* '''[http://clam.iua.upf.edu/doc/CLAM-devel-doxygen/classCLAM_1_1InFilename.html CLAM::InFilename] and [http://clam.iua.upf.edu/doc/CLAM-devel-doxygen/classCLAM_1_1OutFilename.html CLAM::OutFilename]:''' Use them, or its subclasses, for file names to be read (or written). They renders the proper widget on the configuration. Subclasses can specify available extensions for a format.
* '''[http://clam.iua.upf.edu/doc/CLAM-devel-doxygen/classCLAM_1_1DynamicType.html CLAM::DynamicType]:''' Other dynamic types can be embeded as configuration attributes. XML renders them as inner elements. Configuration dialog provides a button that opens a second configuration dialog.
TODO: Screenshots for the Config dialog interface.
== (Only for CLAM <= 1.1) Making the configuration dialogs available to the NetworkEditor ==
From CLAM > 1.1 no action is needed: Configuration dialog are '''automatically available''' to the NetworkEditor.
In older versions this step is required:
* On the NetworkEditor source tree add a cxx file containing the following lines:
#include "MyProcessing.hxx"
#include "RegisterConfiguratorLaunchers.hxx"
STANDARD_PROCESSING_CONFIG_REGISTER(MyProcessing::Config);
== Calling the configurator by hand in your own program ==