ServiceRequester.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 ServiceRequester.cpp
3 
4  ServiceRequester.cpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #include "ServiceRequester.hpp"
40 #include "Service.hpp"
41 #include "internal/mystd.hpp"
42 #include "Logger.hpp"
43 #include "TaskContext.hpp"
44 #include <boost/bind.hpp>
45 
46 #include <utility>
47 
48 namespace RTT
49 {
50  using namespace boost;
51  using namespace detail;
52  using namespace std;
53 
54  ServiceRequester::ServiceRequester(const std::string& name, TaskContext* tc) :
55  mrname(name), mrowner(tc)
56  {
57  }
58 
60  {
61  }
62 
64  {
65  if (mmethods.find(isb.getName()) != mmethods.end())
66  {
67  log(Error) << "OperationCaller with name '" + isb.getName() + "' already present." << endlog();
68  return false;
69  }
70  mmethods.insert(make_pair(isb.getName(), &isb));
71  return true;
72  }
73 
74  std::vector<std::string> ServiceRequester::getOperationCallerNames() const
75  {
76  return keys(mmethods);
77  }
78 
79  std::vector<std::string> ServiceRequester::getRequesterNames() const
80  {
81  return keys(mrequests);
82  }
83 
85  {
86  OperationCallers::iterator it = mmethods.find(name);
87  if (it != mmethods.end())
88  return it->second;
89  return 0;
90  }
91 
93  {
94  for(OperationCallers::iterator it = mmethods.begin(); it != mmethods.end(); ++it)
95  it->second->setCaller( new_owner ? new_owner->engine() : 0);
96 
97  this->mrowner = new_owner;
98 
99  for(Requests::iterator it = mrequests.begin(); it != mrequests.end(); ++it)
100  it->second->setOwner( new_owner );
101  }
102 
104  try {
105  return shared_from_this();
106  } catch( boost::bad_weak_ptr& /*bw*/ ) {
107  log(Error) <<"When using boost < 1.40.0 : You are not allowed to call requires() on a ServiceRequester that does not yet belong to a TaskContext or another ServiceRequester." << endlog();
108  log(Error) <<"Try to avoid using requires() in this case: omit it or use the service requester directly." <<endlog();
109  log(Error) <<"OR: upgrade to boost 1.40.0, then this error will go away." <<endlog();
110  throw std::runtime_error("Illegal use of requires()");
111  }
112  }
113 
114  ServiceRequester::shared_ptr ServiceRequester::requires(const std::string& service_name) {
115  if (service_name == "this")
116  return requires();
117  Requests::iterator it = mrequests.find(service_name);
118  if (it != mrequests.end() )
119  return it->second;
120  shared_ptr sp = boost::make_shared<ServiceRequester>(service_name, mrowner);
121  if ( addServiceRequester(sp) )
122  return sp;
123  return shared_ptr();
124  }
125 
127  if ( mrequests.find( obj->getRequestName() ) != mrequests.end() ) {
128  log(Error) << "Could not add ServiceRequester " << obj->getRequestName() <<": name already in use." <<endlog();
129  return false;
130  }
131 
132  // only set the owner if one is present.
133  if ( mrowner ) {
134  obj->setOwner( mrowner );
135  }
136  mrequests[obj->getRequestName()] = obj;
137  return true;
138  }
139 
141  if (!sp) return false;
142  for (OperationCallers::iterator it = mmethods.begin(); it != mmethods.end(); ++it) {
143  if ( !it->second->ready() ) {
144  if (sp->hasOperation( it->first )) {
145  it->second->setImplementation( sp->getLocalOperation( it->first ), mrowner ? mrowner->engine() : 0 );
146  if ( it->second->ready() ) {
147  log(Debug) << "Successfully set up OperationCaller " << it->first <<endlog();
148  if (!mrowner)
149  log(Debug) << "OperationCaller "<< it->first << " has no caller set: using GlobalEngine."<<endlog();
150  }
151  }
152  if (sp->hasMember( it->first )) {
153  it->second->setImplementationPart( sp->getOperation( it->first ), mrowner ? mrowner->engine() : 0 );
154  if ( it->second->ready() ) {
155  log(Debug) << "Successfully set up OperationCaller " << it->first <<endlog();
156  if (!mrowner)
157  log(Debug) << "OperationCaller "<< it->first << " has no caller set: using GlobalEngine."<<endlog();
158  }
159  }
160  }
161  }
162  if (ready()) {
163  if (!mprovider)
164  mprovider = sp;
165  log(Info) << "Found complete interface of requested service '" << mrname <<"'"<< endlog();
166  return true;
167  }
168 
169  return false;
170  }
171 
173  {
174  for_each(mmethods.begin(), mmethods.end(),
175  boost::bind(&OperationCallerBaseInvoker::disconnect, boost::bind(&OperationCallers::value_type::second, _1) )
176  );
177  }
178 
180  {
181  for (OperationCallers::const_iterator it = mmethods.begin(); it != mmethods.end(); ++it)
182  if ( !it->second->ready() ) {
183  log(Debug) << "ServiceRequester: "<< it->first << " not set up." <<endlog();
184  return false;
185  }
186  return true;
187  }
188 
190  {
191  mmethods.clear();
192  mrequests.clear();
193  }
194 }
virtual const std::string & getName() const =0
RequesterNames getRequesterNames() const
OperationCallers mmethods
virtual bool ready() const
void setOwner(TaskContext *new_owner)
Definition: mystd.hpp:163
boost::shared_ptr< ServiceRequester > shared_ptr
Requests mrequests
the services we implement.
base::OperationCallerBaseInvoker * getOperationCaller(const std::string &name)
boost::shared_ptr< Service > shared_ptr
Definition: Service.hpp:101
ServiceRequester(const std::string &name, TaskContext *owner=0)
Service::shared_ptr mprovider
OperationCallerNames getOperationCallerNames() const
ServiceRequester::shared_ptr requires()
std::vector< typename MapT::key_type > keys(const MapT &map)
Definition: mystd.hpp:151
virtual bool connectTo(Service::shared_ptr sp)
bool addServiceRequester(shared_ptr obj)
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
static Logger & log()
Definition: Logger.hpp:350
const ExecutionEngine * engine() const
Definition: TaskCore.hpp:306
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
bool addOperationCaller(base::OperationCallerBaseInvoker &mbi)


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:28