Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "ServiceRequester.hpp"
00040 #include "Service.hpp"
00041 #include "internal/mystd.hpp"
00042 #include "Logger.hpp"
00043 #include "TaskContext.hpp"
00044 #include <boost/bind.hpp>
00045
00046 #include <utility>
00047
00048 namespace RTT
00049 {
00050 using namespace boost;
00051 using namespace detail;
00052 using namespace std;
00053
00054 ServiceRequester::ServiceRequester(const std::string& name, TaskContext* tc) :
00055 mrname(name), mrowner(tc)
00056 {
00057 }
00058
00059 ServiceRequester::~ServiceRequester()
00060 {
00061 }
00062
00063 bool ServiceRequester::addOperationCaller(OperationCallerBaseInvoker& isb)
00064 {
00065 if (mmethods.find(isb.getName()) != mmethods.end())
00066 {
00067 log(Error) << "OperationCaller with name '" + isb.getName() + "' already present." << endlog();
00068 return false;
00069 }
00070 mmethods.insert(make_pair<std::string, OperationCallerBaseInvoker*> (isb.getName(), &isb));
00071 return true;
00072 }
00073
00074 std::vector<std::string> ServiceRequester::getOperationCallerNames() const
00075 {
00076 return keys(mmethods);
00077 }
00078
00079 std::vector<std::string> ServiceRequester::getRequesterNames() const
00080 {
00081 return keys(mrequests);
00082 }
00083
00084 OperationCallerBaseInvoker* ServiceRequester::getOperationCaller(const std::string& name)
00085 {
00086 OperationCallers::iterator it = mmethods.find(name);
00087 if (it != mmethods.end())
00088 return it->second;
00089 return 0;
00090 }
00091
00092 void ServiceRequester::setOwner(TaskContext *new_owner)
00093 {
00094 for(OperationCallers::iterator it = mmethods.begin(); it != mmethods.end(); ++it)
00095 it->second->setCaller( new_owner ? new_owner->engine() : 0);
00096
00097 this->mrowner = new_owner;
00098 }
00099
00100 ServiceRequester::shared_ptr ServiceRequester::requires() {
00101 try {
00102 return shared_from_this();
00103 } catch( boost::bad_weak_ptr& ) {
00104 log(Error) <<"When using boost < 1.40.0 : You are not allowed to call provides() on a ServiceRequester that does not yet belong to a TaskContext or another ServiceRequester." << endlog();
00105 log(Error) <<"Try to avoid using requires() in this case: omit it or use the service requester directly." <<endlog();
00106 log(Error) <<"OR: upgrade to boost 1.40.0, then this error will go away." <<endlog();
00107 throw std::runtime_error("Illegal use of requires()");
00108 }
00109 }
00110
00111 ServiceRequester::shared_ptr ServiceRequester::requires(const std::string& service_name) {
00112 if (service_name == "this")
00113 return requires();
00114 shared_ptr sp = mrequests[service_name];
00115 if (sp)
00116 return sp;
00117 sp = boost::make_shared<ServiceRequester>(service_name, mrowner);
00118 mrequests[service_name] = sp;
00119 return sp;
00120 }
00121
00122 bool ServiceRequester::addServiceRequester(ServiceRequester::shared_ptr obj) {
00123 if ( mrequests.find( obj->getRequestName() ) != mrequests.end() ) {
00124 log(Error) << "Could not add ServiceRequester " << obj->getRequestName() <<": name already in use." <<endlog();
00125 return false;
00126 }
00127
00128
00129 if ( mrowner ) {
00130 obj->setOwner( mrowner );
00131 }
00132 mrequests[obj->getRequestName()] = obj;
00133 return true;
00134 }
00135
00136 bool ServiceRequester::connectTo( Service::shared_ptr sp) {
00137 for (OperationCallers::iterator it = mmethods.begin(); it != mmethods.end(); ++it) {
00138 if ( !it->second->ready() ) {
00139 if (sp->hasOperation( it->first )) {
00140 it->second->setImplementation( sp->getLocalOperation( it->first ), mrowner ? mrowner->engine() : 0 );
00141 if ( it->second->ready() ) {
00142 log(Debug) << "Successfully set up OperationCaller " << it->first <<endlog();
00143 if (!mrowner)
00144 log(Debug) << "OperationCaller "<< it->first << " has no caller set: using GlobalEngine."<<endlog();
00145 }
00146 }
00147 if (sp->hasMember( it->first )) {
00148 it->second->setImplementationPart( sp->getOperation( it->first ), mrowner ? mrowner->engine() : 0 );
00149 if ( it->second->ready() ) {
00150 log(Debug) << "Successfully set up OperationCaller " << it->first <<endlog();
00151 if (!mrowner)
00152 log(Debug) << "OperationCaller "<< it->first << " has no caller set: using GlobalEngine."<<endlog();
00153 }
00154 }
00155 }
00156 }
00157 if (ready()) {
00158 if (!mprovider)
00159 mprovider = sp;
00160 log(Info) << "Found complete interface of requested service '" << mrname <<"'"<< endlog();
00161 return true;
00162 }
00163
00164 return false;
00165 }
00166
00167 void ServiceRequester::disconnect()
00168 {
00169 for_each(mmethods.begin(), mmethods.end(),
00170 boost::bind(&OperationCallerBaseInvoker::disconnect, boost::bind(&OperationCallers::value_type::second, _1) )
00171 );
00172 }
00173
00174 bool ServiceRequester::ready() const
00175 {
00176 for (OperationCallers::const_iterator it = mmethods.begin(); it != mmethods.end(); ++it)
00177 if ( !it->second->ready() ) {
00178 log(Debug) << "ServiceRequester: "<< it->first << " not set up." <<endlog();
00179 return false;
00180 }
00181 return true;
00182 }
00183
00184 void ServiceRequester::clear()
00185 {
00186 mmethods.clear();
00187 mrequests.clear();
00188 }
00189 }