Orocos Real-Time Toolkit  2.6.0
ServiceRequester.cpp
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     bool ServiceRequester::connectTo( Service::shared_ptr sp) {
00093         for (OperationCallers::iterator it = mmethods.begin(); it != mmethods.end(); ++it) {
00094             if ( !it->second->ready() ) {
00095                 if (sp->hasOperation( it->first )) {
00096                     it->second->setImplementation( sp->getLocalOperation( it->first ), mrowner ? mrowner->engine() : 0 );
00097                     if ( it->second->ready() ) {
00098                         if (mrowner)
00099                             log(Debug) << "Successfully set up OperationCaller " << it->first <<endlog();
00100                         else
00101                             log(Warning) << "OperationCaller "<< it->first << " has no caller set."<<endlog();
00102                     }
00103                 }
00104                 if (sp->hasMember( it->first )) {
00105                     it->second->setImplementationPart( sp->getOperation( it->first ), mrowner ? mrowner->engine() : 0 );
00106                     if ( it->second->ready() ) {
00107                         if (mrowner)
00108                             log(Debug) << "Successfully set up OperationCaller " << it->first <<endlog();
00109                         else
00110                             log(Warning) << "OperationCaller "<< it->first << " has no caller set."<<endlog();
00111                     }
00112                 }
00113             }
00114         }
00115         if (ready()) {
00116             if (!mprovider)
00117                 mprovider = sp;
00118             log(Info) << "Found complete interface of requested service '" << mrname <<"'"<< endlog();
00119             return true;
00120         }
00121 
00122         return false;
00123     }
00124 
00125     void ServiceRequester::disconnect()
00126     {
00127         for_each(mmethods.begin(), mmethods.end(),
00128                  boost::bind(&OperationCallerBaseInvoker::disconnect, boost::bind(&OperationCallers::value_type::second, _1) )
00129                  );
00130     }
00131 
00132     bool ServiceRequester::ready() const
00133     {
00134         for (OperationCallers::const_iterator it = mmethods.begin(); it != mmethods.end(); ++it)
00135             if ( !it->second->ready() ) {
00136                 log(Debug) << "ServiceRequeste: "<< it->first << " not set up." <<endlog();
00137                 return false;
00138             }
00139         return true;
00140     }
00141 }