Advanced Agent
1
Existing C++ code
#include <functional>
#include <unordered_map>
#include <vector>
struct Bottle {
std::string name;
std::string category;
std::string country;
};
class Bar {
public:
typedef std::function<void(const std::string&)> StringCallback;
typedef std::function<void(const Bottle&)> BottleCallback;
typedef std::vector<BottleCallback> BottleCallbacks;
typedef std::vector<Bottle> Selection;
static std::string philosophy();
Bar() = default;
explicit Bar(const Selection& selection);
void addBottle(const std::string& name,
const std::string& category = "n/a",
const std::string& country = "n/a");
Bottle removeBottle(const std::string& name);
void onAdd(const BottleCallback& listener);
void onRemove(const BottleCallback& listener);
std::string prepareDrink(const StringCallback& done) const;
Selection getSelection() const;
private:
std::string _random() const;
BottleCallbacks _addListeners;
BottleCallbacks _removeListeners;
Selection _selection;
};#include "Bar.hpp"
#include <chrono>
#include <iostream>
#include <thread>
std::string Bar::philosophy() {
return "I have mixed drinks about feelings.";
}
Bar::Bar(const Selection& selection) : _selection(selection) {}
void Bar::addBottle(const std::string& name,
const std::string& category,
const std::string& country) {
Bottle bottle = {name, category, country};
_selection.push_back(bottle);
for (const auto& notify : _addListeners) notify(bottle);
}
Bottle Bar::removeBottle(const std::string& name) {
Selection filtered;
Bottle bottle;
for (const auto& x : _selection) {
if (bottle.name.empty() && (x.name == name)) {
for (const auto& notify : _removeListeners) notify(x);
bottle = x;
continue;
}
filtered.push_back(x);
}
if (bottle.name.empty()) {
throw std::runtime_error("Sorry, this bottle is not in our selection");
}
_selection = filtered;
return bottle;
}
void Bar::onAdd(const Bar::BottleCallback& listener) {
_addListeners.push_back(listener);
}
void Bar::onRemove(const Bar::BottleCallback& listener) {
_removeListeners.push_back(listener);
}
std::string Bar::prepareDrink(const Bar::StringCallback& done) const {
const std::vector<std::string> v = {_random(), _random(), _random()};
std::thread([=]() {
std::this_thread::sleep_for(std::chrono::seconds(3));
done("Your drink is ready! I mixed " + v[0] + " with " + v[1] +
" and a bit of " + v[2] + ".");
}).detach();
return "In preparation...";
}
Bar::Selection Bar::getSelection() const {
return _selection;
}
std::string Bar::_random() const {
if (_selection.size() == 0) {
throw std::runtime_error("I searched, but couldn\'t find any bottles");
}
int index = std::rand() % _selection.size();
return _selection[index].name;
}2
Make it accessible from remote
#include <vrpc/adapter.hpp>
#include <vrpc/agent.hpp>
#include "Bar.hpp"
namespace vrpc {
// Adapt custom type: Bottle
VRPC_DEFINE_TYPE(Bottle, name, category, country);
// Adapt static function
VRPC_STATIC_FUNCTION(Bar, std::string, philosophy)
// Adapt constructors
VRPC_CTOR(Bar)
VRPC_CTOR(Bar, const Bar::Selection&)
// Adapt member functions
VRPC_MEMBER_FUNCTION_X(Bar,
void, "",
addBottle, "Adds a bottle to the bar",
const std::string&, "name", required(), "name of the bottle",
const std::string&, "category", "n/a", "category of the drink",
const std::string&, "country", "n/a", "country of production")
VRPC_MEMBER_FUNCTION(Bar, Bottle, removeBottle, const std::string&)
VRPC_MEMBER_FUNCTION(Bar, void, onAdd, VRPC_CALLBACK(const Bottle&))
VRPC_MEMBER_FUNCTION(Bar, void, onRemove, VRPC_CALLBACK(const Bottle&))
VRPC_CONST_MEMBER_FUNCTION(Bar, std::string, prepareDrink, VRPC_CALLBACK(const std::string&))
VRPC_CONST_MEMBER_FUNCTION(Bar, Bar::Selection, getSelection)
} // namespace vrpc
int main(int argc, char** argv) {
auto agent = vrpc::VrpcAgent::from_commandline(argc, argv);
if (agent) agent->serve();
return EXIT_SUCCESS;
}3
Compilation
TARGET = vrpc-bar-agent
CPPFLAGS = -I. -pthread -fPIC -m64 -O3 -std=c++14
LDFLAGS = -pthread
LDLIBS =
SRCS := $(shell find ./src -name *.cpp)
OBJS := $(addsuffix .o,$(basename $(SRCS)))
DEPS := $(OBJS:.o=.d)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS)
.PHONY: clean
clean:
$(RM) $(TARGET) $(OBJS) $(DEPS)
-include $(DEPS)make./vrpc-bar-agentConnecting to message broker... [OK]Last updated