Generic Components
To facilitate reuse, generic components can be parametrized with type parameters. The type parameters can then be used as types for ports, parameters, or other entities in the behavior definition of a component. For defining multiple type parameters, one separates them using commas:
component Foo<K, V> { /*...*/}
The following example shows a generic component type definition:
/* Merges streams by selecting the element of one of them at a time */
component Selector<T>(SelectionRule<T, T, Boolean> rule) {
port in T elementA,
in T elementB,
out T selectedElement;
}
T
can be used anywhere where a non-generic type could have been used.
Instantiation
When components with generic type parameters are used during decomposition, types have to be bound.
In the following, we bind the type parameter <T>
of our previous example to WindowButtonMoveEvent
.
component HumanMachineInterface {
port out WindowButtonMoveEvent buttonBackLeftEvent;
// ...
Selector<WindowButtonMoveEvent> signalSelector(/*...*/);
signalSelector.selectedElement -> buttonBackLeftEvent;
// ...
}
component Oracle<T> {
port out T prediction;
Database<T> database; // Used for predicting values
// Other sub components ...
}
Inheritance
When extending from a generic component, all its type parameters must be bound. Using newly defined type parameters for this is also allowed.
component Selector<T>(/*...*/) extends StreamMerger<T> {
// ...
}
Upper bounds
component AgeFilter<T extends Person>(int minAge) {
port in T unfiltered;
port out T filtered;
compute {
// Using information of the upper bound to access the age of the incoming element.
if (unfiltered.age >= minAge) {
filtered = unfiltered;
}
}
}
&
s:
component Foo<K extends Worker & Student, V> { /*...*/ }