An actuator is a generic callable that may invoke a list of actions(callables of type std::function<...>).
Its goal is to provide a light and simple mechanism to connect components that want to communicate with each other. It works similar as the "signal and slots" mechanisms from other frameworks, but much simplified.
Modern programming languages do not offer class intrinsic interfaces that would improve significantly how objects are connected and how they communicate.
Instead, languages, like C++, are using external interfaces, that are not only cluttering the code, but they don't feel "natural" as they are opposed to
what an interface is in reality. Basically the objects and interfaces are not separated, and the interface is intrinsic to the object(think on the cogs in a mechanism).
A generic callable is an attempt to mitigate this problem. async implementation is such use case.
An actuator provides the results of all actions in a vector, in the same order as the actions were added.
void rotate_shapes(const std::vector<shape*>& shapes, int angle)
{
for (const auto& s : shapes)
{
s->rotate(angle);
}
}
std::shared_ptr<triangle> t(new triangle);
std::shared_ptr<circle> c(new circle);
std::shared_ptr<square> s(new square);
// using polymorphism
std::vector<shape*> shapes;
shapes.push_back(t.get());
shapes.push_back(c.get());
shapes.push_back(s.get());
rotate_shapes(shapes, 10);
// using actuator
auto action1 = untangle::bind(t, &triangle::rotate);
auto action2 = untangle::bind(c, &circle::rotate);
auto action3 = untangle::bind(s, &square::rotate);
auto actuator_rotate = untangle::connect(action1, action2, action3);
actuator_rotate(20);For convenience there are provided helpers methods to "connect" to an initial list of "actions", or to create bindings to class methods.
Please check the manual in doc/refman.pdf for further references.