Class reactor


  • This tutorial assumes that RAPP API is installed and built
  • This tutorial uses the 0.7.0 version of the C++ API

Running cloud calls using lambdas may not always be the best solution. Under certain conditions a class which handles callbacks may be a better. In this scenario we define and implement a class which does just that. The reactor class methods will be used to handle cloud replies:

class reactor
{
public:

    void handle_face(std::vector<rapp::object::face> faces)
    {        
        std::cout << "Found " << faces.size() << " faces!" << std::endl;
    }

    void reactor::handle_ontology_sub(std::vector<std::string> classes)
    {        
        std::cout << "Sub classes: " << std::endl;
        for (const auto & str : classes) {
            std::cout << str << std::endl;
        }    
    }

    void handle_weather(std::vector<std::string> weather) 
    {
        std::cout << "Temperature: " << weather.at(1) << std::endl;
        std::cout << "Humidity: " << weather.at(3) << std::endl;
        std::cout << "Wind speed: " << weather.at(6) << std::endl;
    }

    ...
};

The reactor class also wraps around a service_controller and thus controls the calls.

class reactor
{
    ...

private:
    rapp::cloud::service_controller ctrl_;
};

We construct it using:

reactor::reactor(rapp::cloud::platform info)
: ctrl_(info)
{}

Making the calls is done using the run method. We also use it to bind to the handler methods.

void reactor::run(rapp::object::picture pic, std::string object, std::string city)
{
    ctrl_.make_calls(face_detection(pic, false, std::bind(&reactor::handle_face, this, std::placeholders::_1)),
                     weather_report_current(city, "", 0, std::bind(&reactor::handle_weather, this, std::placeholders::_1)),
                     ontology_subclasses_of(object, true, std::bind(&reactor::handle_ontology_sub, this, std::placeholders::_1)));
}

Thus this method will run three different cloud calls as a batch job, whilst re-using its own methods to receive the replies. Because we're using class methods we have to either use std::function class members, or use a bind (either std::bind or boost::bind) to the class methods. A lambda callback could also be used, but it would have to capture this.

Constructing a unique pointer to our reactor class is done like so:

rapp::cloud::platform info = {"rapp.ee.auth.gr", "9001", "rapp_token"}; 
auto my_reactor = std::make_unique<reactor>(info);

And finally we execute the run method:

my_reactor->run(pict, "Toy", "Madrid");

The reply you'll receive is:

Sub classes:
http://knowrob.org/kb/knowrob.owl#Toy
Temperature: 79.36
Humidity: 0.26
Wind speed: 2.5
Found 1 faces!

Therefore, for more sophisticated use of a group of cloud calls, especially if post-processing or pre-processing is required, or if taking an object-oriented approach, a reactor class may be better suited.