-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCreating_a_minimal_processing_object.mw
100 lines (76 loc) · 3.56 KB
/
Creating_a_minimal_processing_object.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
A processing is one of the boxes you can connect on the NetworkEditor.
They perform a process on some input data and writes some output data.
Sources and sinks for a processing are InPort's and OutPort's.
Ports can be templated to any copiable data.
Ports cooperate with the flow control to move the data arround.
Although it is not the recommended way,
you can also use the processing directly as a function passing
the data directly to the Do overload which has parameters.
Here is a minimal implementation of a processing object with a single input and a single output:
[[Image:MyProcessing.png|thumb|How the processing will look like on the NetworkEditor]]
<pre>
#ifndef MyProcessing_hxx
#define MyProcessing_hxx
#include <CLAM/InPort.hxx>
#include <CLAM/OutPort.hxx>
#include <CLAM/Processing.hxx>
// Those two configuration types could be the ones you choose.
// Your own ones or any type already in CLAM.
#include "MyInputDataType.hxx"
#include "MyOutputDataType.hxx"
class MyProcessing : public CLAM::Processing
{
CLAM::InPort<MyInputDataType> mIn;
CLAM::OutPort<MyOutputDataType> mOut;
public:
const char* GetClassName() const { return "MyProcessing"; }
MyProcessing(const Config& config = Config())
: mIn("My Input", this)
, mOut("My Output", this)
{
Configure( config );
}
bool Do()
{
bool result = Do(mIn.GetData(), mOut.GetData());
// Tell the ports this is done
mIn.Consume();
mOut.Produce();
return result;
}
bool Do(const MyInputDataType& in, MyOutputDataType& out)
{
// Your implementation
}
};
#endif // MyProcessing_hxx
</pre>
== MyProcessing.cxx ==
[[Image:MyProcessing-ProcessingTree.png|thumb|MyProcessing available at the end of the 'Spectral Transformations' group]]
As the class methods get verbose, it is convenient to move the implementation to the cxx. To keep the example short and easy to follow and copy, we kept all the implementations on the hxx.
But, still, what needs always be on the cxx file is the factory registration.
#include "MyProcessing.hxx"
#include <CLAM/ProcessingFactory.hxx>
static const char * metadata[] = {
"key", "MyProcessing",
"category", "Spectral Transformations",
0
};
static CLAM::FactoryRegistrator<CLAM::ProcessingFactory, MyProcessing> registrator(metadata);
You can blindly copy and change 'MyProcessing' by the name of your actual class and the category.
The category is the processing tool box category your processing will appear.
The key is the name you can provide the factory to create actual processing objects.
The constructor of this FactoryRegistrator, which is called before main,
just adds the Processing Factory instructions on how to create a MyProcessing object
when you ask for the label "MyProcessing".
It also relates the Processing to different metadata.
For instance, the 'category' is the category that can be browsed in the NetworkEditor processing toolbox.
If no 'category' is provided, such processing can be instanciated by the factory but
the NetworkEditor will not display it in the processing tree.
TODO: Explain other used metadata (icon...)
== Further reading ==
* [[Processings with controls]] If you want the processing to receive or send asynchronous data.
* [[Processings with configuration]] If you want some aspects of the processing to be configurable.
* [[Building a processing library]] If you want your processing to become part of a CLAM plugin library.
* [[Defining a ProcessingComposite]] If you want your processing to be an aggregation of processings.
* [[Using custom data token types]] if you want to set the port color, type name... for your custom data type.