Service.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 Service.cpp
3 
4  Service.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 "Service.hpp"
40 #include "TaskContext.hpp"
41 #include <algorithm>
42 #include "internal/mystd.hpp"
43 #include <algorithm>
44 
45 namespace RTT {
46  using namespace detail;
47  using namespace std;
48  using namespace boost;
49 
50  Service::shared_ptr Service::Create(const std::string& name, TaskContext* owner) {
51  shared_ptr ret(new Service(name,owner));
52  if (owner)
53  owner->provides()->addService( ret );
54  return ret;
55  }
56 
57  Service::Service(const std::string& name, TaskContext* owner)
58  : mname(name),
59  mowner(owner),
60  parent()
61  {
62  // Inform DataFlowInterface.
63  mservice = this;
64  }
65 
67  {
68  clear();
69  }
70 
71  vector<string> Service::getProviderNames() const {
72  return keys(services);
73  }
74 
76  if(this->getOwner())
77  return this->getOwner()->engine();
78  return NULL;
79  }
80 
82  if ( services.find( obj->getName() ) != services.end() ) {
83  log(Error) << "Could not add Service " << obj->getName() <<": name already in use." <<endlog();
84  return false;
85  }
86  // we pass and store a shared ptr in setParent, so we hack it like this:
87  shared_ptr me;
88  try {
89  me = shared_from_this();
90  } catch ( boost::bad_weak_ptr& bw ) {
91  me.reset(this); // take ownership
92  }
93  obj->setParent( me );
94 
95  // only set the owner if one is present.
96  if ( mowner ) {
97  obj->setOwner( mowner );
98  }
99  services[obj->getName()] = obj;
100  return true;
101  }
102 
103  void Service::removeService( string const& name) {
104  // carefully written to avoid destructor to call back on us when called from clear().
105  if ( services.count(name) ) {
106  shared_ptr sp = services.find(name)->second;
107  services.erase(name);
108  sp->setParent(Service::shared_ptr());
109  sp.reset(); // this possibly deletes.
110  }
111  }
112 
114  try {
115  return shared_from_this();
116  } catch( boost::bad_weak_ptr& /*bw*/ ) {
117  log(Error) <<"When using boost < 1.40.0 : You are not allowed to call provides() on a Service that does not yet belong to a TaskContext or another Service (for example in a constructor)." << endlog();
118  log(Error) <<"Try to avoid using provides() in this case: omit it or use the service directly." <<endlog();
119  throw std::runtime_error("Illegal use of provides()");
120  }
121  }
122 
123  Service::shared_ptr Service::provides(const std::string& service_name) {
124  shared_ptr sp = getService(service_name);
125  if (sp)
126  return sp;
127  sp = boost::make_shared<Service>(service_name, mowner);
128  if ( addService(sp) )
129  return sp;
130  return shared_ptr();
131  }
132 
133  Service::shared_ptr Service::getService(const std::string& service_name) {
134  if (service_name == "this")
135  return provides();
136  Services::iterator it = services.find(service_name);
137  if (it != services.end() )
138  return it->second;
139  return shared_ptr();
140  }
141 
143  {
144  Logger::In in("Service::getOperation");
145  if ( this->hasMember(name ) ) {
146  return this->getPart(name);
147  }
148  log(Warning) << "No such operation in service '"<< getName() <<"': "<< name <<endlog();
149  return 0;
150  }
151 
152  bool Service::resetOperation(std::string name, base::OperationBase* impl)
153  {
154  if (!hasOperation(name))
155  return false;
156  simpleoperations[name] = impl;
157  return true;
158  }
159 
160  bool Service::setOperationThread(std::string const& name, ExecutionThread et)
161  {
162  if ( !hasOperation(name) )
163  return false;
165  OperationCallerInterface::shared_ptr oci = dynamic_pointer_cast<OperationCallerInterface>(di);
166  if (oci) {
167  return oci->setThread( et, getOwner() ? getOwner()->engine() : 0 );
168  }
169  return false;
170  }
171 
172  bool Service::hasService(const std::string& service_name) {
173  if (service_name == "this")
174  return true;
175  return services.find(service_name) != services.end();
176  }
177 
179  {
180  Logger::In in("Service::addLocalOperation");
181  if ( op.getName().empty() ) {
182  log(Error) << "Failed to add Operation: '"<< op.getName() <<"' has no name." <<endlog();
183  return false;
184  }
185  // don't check ready() since the op may not have an owner yet:
186  if ( !op.getImplementation() ) {
187  log(Error) << "Failed to add Operation: '"<< op.getName() <<"' is not ready: not bound to a function." <<endlog();
188  return false;
189  }
190  if ( simpleoperations.count( op.getName() ) ) {
191  log(Warning) << "While adding Operation: '"<< op.getName() <<"': replacing previously added operation." <<endlog();
192  this->removeOperation(op.getName());
193  }
194  simpleoperations[op.getName()] = &op;
195  // finally set the (new) owner:
196  if (mowner) {
197  // also updates the Executor:
198  op.setOwner(mowner->engine());
199  }
200  return true;
201  }
202 
203  boost::shared_ptr<base::DisposableInterface> Service::getLocalOperation( std::string name ) {
204  if ( hasOperation(name) ) {
205  return simpleoperations.find(name)->second->getImplementation();
206  }
207  return boost::shared_ptr<base::DisposableInterface>();
208  }
209 
211  {
212  while ( !simpleoperations.empty() )
213  {
214  simpleoperations.erase(simpleoperations.begin() );
215  }
216 
217  for( OperationList::const_iterator it = ownedoperations.begin(); it != ownedoperations.end(); ++it )
218  {
219  delete *it;
220  }
221  ownedoperations.clear();
222 
225  while ( !services.empty() ) {
226  this->removeService( services.begin()->first );
227  }
228  }
229 
230  std::vector<std::string> Service::getOperationNames() const
231  {
232  return keys(simpleoperations);
233  //return getNames();
234  }
235 
236  bool Service::hasOperation(const std::string& name) const
237  {
238  return simpleoperations.count(name) == 1;
239  //return hasMember(name);
240  }
241 
242  void Service::removeOperation(const std::string& name)
243  {
244  if (!hasOperation(name))
245  return;
246  OperationList::iterator it = find(ownedoperations.begin(), ownedoperations.end(), simpleoperations.find(name)->second );
247  if (it != ownedoperations.end()) {
248  delete *it;
249  ownedoperations.erase(it);
250  }
251  simpleoperations.erase( name );
253  }
254  void Service::setOwner(TaskContext* new_owner) {
255  for( SimpleOperations::iterator it= simpleoperations.begin(); it != simpleoperations.end(); ++it)
256  it->second->setOwner( new_owner ? new_owner->engine() : 0);
257 
258  this->mowner = new_owner;
259 
260  for( Services::iterator it= services.begin(); it != services.end(); ++it)
261  it->second->setOwner( new_owner );
262  }
263 
265  parent = p;
266  }
267 
269  return internal::OperationCallerC( getPart(name), name, caller );
270  }
271 
272 }
const std::string & getName() const
Definition: Service.hpp:139
void setParent(shared_ptr new_parent)
Definition: Service.cpp:264
TaskContext * getOwner() const
Definition: Service.hpp:185
Service::shared_ptr provides()
Definition: Service.cpp:113
bool hasOperation(const std::string &name) const
Definition: Service.cpp:236
static Service::shared_ptr Create(const std::string &name, TaskContext *owner=0)
Definition: Service.cpp:50
Service::shared_ptr provides()
boost::shared_ptr< base::DisposableInterface > getLocalOperation(std::string name)
Definition: Service.cpp:203
Service(const std::string &name, TaskContext *owner=0)
Definition: Service.cpp:57
bool setThread(ExecutionThread et, ExecutionEngine *executor)
virtual void removeService(std::string const &service_name)
Definition: Service.cpp:103
Definition: mystd.hpp:163
Services services
the services we implement.
Definition: Service.hpp:563
bool hasMember(const std::string &name) const
virtual ProviderNames getProviderNames() const
Definition: Service.cpp:71
void removeOperation(const std::string &name)
Definition: Service.cpp:242
bool resetOperation(std::string name, base::OperationBase *impl)
Definition: Service.cpp:152
boost::shared_ptr< OperationCallerInterface > shared_ptr
boost::shared_ptr< Service > shared_ptr
Definition: Service.hpp:101
OperationInterfacePart * getPart(const std::string &name)
Service * getService() const
SimpleOperations simpleoperations
Definition: Service.hpp:568
virtual ~Service()
Definition: Service.cpp:66
virtual bool addService(shared_ptr obj)
Definition: Service.cpp:81
bool hasService(const std::string &service_name)
Definition: Service.cpp:172
bool addLocalOperation(base::OperationBase &op)
Definition: Service.cpp:178
TaskContext * mowner
Definition: Service.hpp:572
virtual DisposableInterface::shared_ptr getImplementation()=0
boost::shared_ptr< DisposableInterface > shared_ptr
std::vector< std::string > getOperationNames() const
Definition: Service.cpp:230
virtual RTT_API boost::shared_ptr< base::DisposableInterface > getLocalOperation() const
OperationList ownedoperations
Definition: Service.hpp:569
std::vector< typename MapT::key_type > keys(const MapT &map)
Definition: mystd.hpp:151
ExecutionEngine * getOwnerExecutionEngine() const
Definition: Service.cpp:75
void setOwner(ExecutionEngine *ee)
OperationInterfacePart * getOperation(std::string name)
Definition: Service.cpp:142
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
bool setOperationThread(std::string const &name, ExecutionThread et)
Definition: Service.cpp:160
const std::string & getName()
void setOwner(TaskContext *new_owner)
Definition: Service.cpp:254
static Logger & log()
Definition: Logger.hpp:350
internal::OperationCallerC create(std::string name, ExecutionEngine *caller)
Definition: Service.cpp:268
void remove(const std::string &name)
const ExecutionEngine * engine() const
Definition: TaskCore.hpp:306
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
void clear()
Definition: Service.cpp:210
ExecutionThread
shared_ptr parent
Definition: Service.hpp:573


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