iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tests/test-ResultsSyntax.C
/*! @file
@author Unknown
@copyright GNU Public License (GPL v3)
@section License
@verbatim
// ////////////////////////////////////////////////////////////////////////
// The iLab Neuromorphic Robotics Toolkit (NRT) //
// Copyright 2010-2012 by the University of Southern California (USC) //
// and the iLab at USC. //
// //
// iLab - University of Southern California //
// Hedco Neurociences Building, Room HNB-10 //
// Los Angeles, Ca 90089-2520 - USA //
// //
// See http://ilab.usc.edu for information about this project. //
// ////////////////////////////////////////////////////////////////////////
// This file is part of The iLab Neuromorphic Robotics Toolkit. //
// //
// The iLab Neuromorphic Robotics Toolkit is free software: you can //
// redistribute it and/or modify it under the terms of the GNU General //
// Public License as published by the Free Software Foundation, either //
// version 3 of the License, or (at your option) any later version. //
// //
// The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
// that it will be useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with The iLab Neuromorphic Robotics Toolkit. If not, see //
// <http://www.gnu.org/licenses/>. //
// ////////////////////////////////////////////////////////////////////////
@endverbatim */
class MessageSend : public nrt::MessageBase
{ public: template<class Archive> inline void serialize(Archive& ar) { } };
class MessageReturn : public nrt::MessageBase
{
public:
MessageReturn() {}
MessageReturn(std::string const & _id) : id(_id) { }
std::string id;
template<class Archive> inline void serialize(Archive& ar) { ar( id ); }
};
NRT_DECLARE_MESSAGEPOSTER_PORT(TheRequest, MessageSend, MessageReturn, "Post/Recieve Request");
NRT_DECLARE_MESSAGEPOSTER_PORT(AsyncPost, nrt::Message<std::string>, void, "An Async Message");
class SendingModule : public nrt::Module,
public nrt::MessagePoster<TheRequest, AsyncPost>
{
public:
void doPost()
{
{
std::unique_ptr<nrt::Message<std::string>> asyncmsg(new nrt::Message<std::string>("hello world!"));
AsyncPost::post(asyncmsg);
// #0 The following is the most explicit method which allows for maximum flexibility in exception handling
std::unique_ptr<MessageSend> msg(new MessageSend);
TheRequest::PostResultsType results = TheRequest::post(msg);
TheRequest::PostResultsType::iterator it = results.begin();
for(; it != results.end(); ++it)
{
try
{
TheRequest::PostResultsType::ResultFuture res = *it;
NRT_INFO("Method 0. Got A Result From " << res.get()->id);
}
{ NRT_INFO("Method 0. Caught Exception: " << e.what()); }
}
}
{
// #1 The following is a convenient way to do #0 using a range-based-for loop
std::unique_ptr<MessageSend> msg(new MessageSend);
for (typename TheRequest::PostResultsType::ResultFuture res : TheRequest::post(msg))
{
try
{
NRT_INFO("Method 1. Got A Result From " << res.get()->id);
}
{ NRT_INFO("Method 1. Caught Exception: " << e.what()); }
}
}
{
std::unique_ptr<MessageSend> msg(new MessageSend);
// #2 A more concise, short-hand for #1. This method requires the user to memorize only the ::post() syntax, and to remember
// to call res.get(). Notice that the auto resolves to a MessagePosterResults, _not_ a shared_ptr.
for(auto res : TheRequest::post(msg))
{
try
{ NRT_INFO("Method 2. Got A Result From " << res.get()->id); }
{ NRT_INFO("Method 2. Caught Exception: " << e.what()); }
}
}
{
std::unique_ptr<MessageSend> msg(new MessageSend);
// #3 The simplest method sacrifices fine-grained exception handling/concurrency control for simplicity and clarity. Notice that we're relying on
// the typecasting operator of MessagePosterResult::Result.
try
{
for(std::shared_ptr<MessageReturn const> retmsg : TheRequest::post(msg))
{
NRT_INFO("Method 3. Got A Result From " << retmsg->id);
}
}
{ NRT_INFO("Method 3. Caught Exception: " << e.what()); }
}
};
};
NRT_DECLARE_MESSAGESUBSCRIBER_PORT(TheResponse, MessageSend, MessageReturn, "Post/Recieve Request");
class RespondingModule : public nrt::Module,
public nrt::MessageSubscriber<TheResponse>,
public nrt::MessageChecker<AsyncCheck>
{
public:
RespondingModule(std::string const & id) : nrt::Module("Responder" + id) { }
std::unique_ptr<MessageReturn> onMessage(TheResponse::InPtr m)
{
NRT_INFO(meta().instanceName << " recieved Request... Checking for a message");
for(std::shared_ptr<nrt::Message<std::string> const> checkmsg : AsyncCheck::check(nrt::MessageCheckerPolicy::Any))
{
NRT_INFO("Got A Check'd Message: " << checkmsg->value());
}
usleep(100000);
if (meta().instanceName == "Responder3")
throw nrt::exception::ModuleException(this, "", meta().instanceName + " doesn't like this request");
return std::unique_ptr<MessageReturn>(new MessageReturn(meta().instanceName));
}
};
int main(int argc, char const* argv[])
{
// Get a handle onto our Blackboard:
// Connect command-line args to Blackboard:
bb.setCommandLineArgs(argc, argv);
auto s = bb.addModule<SendingModule>("sender");
s->TheRequest::setTopic("request");
s->AsyncPost::setTopic("async");
auto r1 = bb.addModule<RespondingModule>("1");
r1->TheResponse::setTopicFilter("request");
r1->AsyncCheck::setTopicFilter("async");
auto r2 = bb.addModule<RespondingModule>("2");
r2->TheResponse::setTopicFilter("request");
r2->AsyncCheck::setTopicFilter("async");
auto r3 = bb.addModule<RespondingModule>("3");
r3->TheResponse::setTopicFilter("request");
r3->AsyncCheck::setTopicFilter("async");
auto r4 = bb.addModule<RespondingModule>("4");
r4->TheResponse::setTopicFilter("request");
r4->AsyncCheck::setTopicFilter("async");
bb.launch();
NRT_DEBUG("Starting Post Sequences");
s->doPost();
NRT_DEBUG("Finished Post Sequences");
return 0;
}