ServiceRequester.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:55:18 CEST 2010  ServiceRequester.cpp
00003 
00004                         ServiceRequester.cpp -  description
00005                            -------------------
00006     begin                : Tue September 07 2010
00007     copyright            : (C) 2010 The SourceWorks
00008     email                : peter@thesourceworks.com
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
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& /*bw*/ ) {
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         // only set the owner if one is present.
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 }


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:15:53