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 "Service.hpp"
00040 #include "TaskContext.hpp"
00041 #include <algorithm>
00042 #include "internal/mystd.hpp"
00043 #include <boost/lambda/lambda.hpp>
00044 #include <boost/lambda/construct.hpp>
00045 #include <algorithm>
00046
00047 namespace RTT {
00048 using namespace detail;
00049 using namespace std;
00050 using namespace boost;
00051
00052 Service::shared_ptr Service::Create(const std::string& name, TaskContext* owner) {
00053 shared_ptr ret(new Service(name,owner));
00054 if (owner)
00055 owner->provides()->addService( ret );
00056 return ret;
00057 }
00058
00059 Service::Service(const std::string& name, TaskContext* owner)
00060 : mname(name),
00061 mowner(owner),
00062 parent()
00063 {
00064
00065 mservice = this;
00066 }
00067
00068 Service::~Service()
00069 {
00070 clear();
00071 }
00072
00073 vector<string> Service::getProviderNames() const {
00074 return keys(services);
00075 }
00076
00077 ExecutionEngine* Service::getOwnerExecutionEngine() const {
00078 if(this->getOwner())
00079 return this->getOwner()->engine();
00080 return NULL;
00081 }
00082
00083 bool Service::addService( Service::shared_ptr obj ) {
00084 if ( services.find( obj->getName() ) != services.end() ) {
00085 log(Error) << "Could not add Service " << obj->getName() <<": name already in use." <<endlog();
00086 return false;
00087 }
00088
00089 shared_ptr me;
00090 try {
00091 me = shared_from_this();
00092 } catch ( boost::bad_weak_ptr& bw ) {
00093 me.reset(this);
00094 }
00095 obj->setParent( me );
00096
00097
00098 if ( mowner ) {
00099 obj->setOwner( mowner );
00100 }
00101 services[obj->getName()] = obj;
00102 return true;
00103 }
00104
00105 void Service::removeService( string const& name) {
00106
00107 if ( services.count(name) ) {
00108 shared_ptr sp = services.find(name)->second;
00109 services.erase(name);
00110 sp.reset();
00111 }
00112 }
00113
00114 Service::shared_ptr Service::provides() {
00115 try {
00116 return shared_from_this();
00117 } catch( boost::bad_weak_ptr& ) {
00118 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();
00119 log(Error) <<"Try to avoid using provides() in this case: omit it or use the service directly." <<endlog();
00120 throw std::runtime_error("Illegal use of provides()");
00121 }
00122 }
00123
00124 Service::shared_ptr Service::provides(const std::string& service_name) {
00125 if (service_name == "this")
00126 return provides();
00127 shared_ptr sp = services[service_name];
00128 if (sp)
00129 return sp;
00130 sp = boost::make_shared<Service>(service_name, mowner);
00131 sp->setOwner( mowner );
00132
00133 shared_ptr me;
00134 try {
00135 me = shared_from_this();
00136 } catch ( boost::bad_weak_ptr& bw ) {
00137 me.reset(this);
00138 }
00139 sp->setParent( me );
00140 services[service_name] = sp;
00141 return sp;
00142 }
00143
00144 Service::shared_ptr Service::getService(const std::string& service_name) {
00145 Services::iterator it = services.find(service_name);
00146 if (it != services.end() )
00147 return it->second;
00148 return shared_ptr();
00149 }
00150
00151 OperationInterfacePart* Service::getOperation( std::string name )
00152 {
00153 Logger::In in("Service::getOperation");
00154 if ( this->hasMember(name ) ) {
00155 return this->getPart(name);
00156 }
00157 log(Warning) << "No such operation in service '"<< getName() <<"': "<< name <<endlog();
00158 return 0;
00159 }
00160
00161 bool Service::resetOperation(std::string name, base::OperationBase* impl)
00162 {
00163 if (!hasOperation(name))
00164 return false;
00165 simpleoperations[name] = impl;
00166 return true;
00167 }
00168
00169 bool Service::setOperationThread(std::string const& name, ExecutionThread et)
00170 {
00171 if ( !hasOperation(name) )
00172 return false;
00173 DisposableInterface::shared_ptr di = getOperation(name)->getLocalOperation();
00174 OperationCallerInterface::shared_ptr oci = dynamic_pointer_cast<OperationCallerInterface>(di);
00175 if (oci) {
00176 return oci->setThread( et, getOwner() ? getOwner()->engine() : 0 );
00177 }
00178 return false;
00179 }
00180
00181 bool Service::hasService(const std::string& service_name) {
00182 if (service_name == "this")
00183 return true;
00184 return services.find(service_name) != services.end();
00185 }
00186
00187 bool Service::addLocalOperation( OperationBase& op )
00188 {
00189 Logger::In in("Service::addLocalOperation");
00190 if ( op.getName().empty() ) {
00191 log(Error) << "Failed to add Operation: '"<< op.getName() <<"' has no name." <<endlog();
00192 return false;
00193 }
00194
00195 if ( !op.getImplementation() ) {
00196 log(Error) << "Failed to add Operation: '"<< op.getName() <<"' is not ready: not bound to a function." <<endlog();
00197 return false;
00198 }
00199 if ( simpleoperations.count( op.getName() ) ) {
00200 log(Warning) << "While adding Operation: '"<< op.getName() <<"': replacing previously added operation." <<endlog();
00201 this->removeOperation(op.getName());
00202 }
00203 simpleoperations[op.getName()] = &op;
00204
00205 if (mowner) {
00206
00207 op.setOwner(mowner->engine());
00208 }
00209 return true;
00210 }
00211
00212 boost::shared_ptr<base::DisposableInterface> Service::getLocalOperation( std::string name ) {
00213 if ( hasOperation(name) ) {
00214 return simpleoperations.find(name)->second->getImplementation();
00215 }
00216 return boost::shared_ptr<base::DisposableInterface>();
00217 }
00218
00219 void Service::clear()
00220 {
00221 while ( !simpleoperations.empty() )
00222 {
00223 simpleoperations.erase(simpleoperations.begin() );
00224 }
00225
00226 for_each(ownedoperations.begin(),ownedoperations.end(), lambda::delete_ptr() );
00227 ownedoperations.clear();
00228
00229 OperationInterface::clear();
00230 ConfigurationInterface::clear();
00231 while ( !services.empty() ) {
00232 this->removeService( services.begin()->first );
00233 }
00234 }
00235
00236 std::vector<std::string> Service::getOperationNames() const
00237 {
00238 return keys(simpleoperations);
00239
00240 }
00241
00242 bool Service::hasOperation(const std::string& name) const
00243 {
00244 return simpleoperations.count(name) == 1;
00245
00246 }
00247
00248 void Service::removeOperation(const std::string& name)
00249 {
00250 if (!hasOperation(name))
00251 return;
00252 OperationList::iterator it = find(ownedoperations.begin(), ownedoperations.end(), simpleoperations.find(name)->second );
00253 if (it != ownedoperations.end()) {
00254 delete *it;
00255 ownedoperations.erase(it);
00256 }
00257 simpleoperations.erase( name );
00258 OperationInterface::remove(name);
00259 }
00260 void Service::setOwner(TaskContext* new_owner) {
00261 for( SimpleOperations::iterator it= simpleoperations.begin(); it != simpleoperations.end(); ++it)
00262 it->second->setOwner( new_owner ? new_owner->engine() : 0);
00263
00264 this->mowner = new_owner;
00265
00266 for( Services::iterator it= services.begin(); it != services.end(); ++it) {
00267 it->second->setOwner( new_owner );
00268 if (new_owner) {
00269
00270 shared_ptr me;
00271 try {
00272 me = shared_from_this();
00273 } catch ( boost::bad_weak_ptr& bw ) {
00274 me.reset(this);
00275 }
00276 it->second->setParent( me );
00277 }
00278 }
00279 }
00280
00281 void Service::setParent( Service::shared_ptr p) {
00282 parent = p;
00283 }
00284
00285 internal::OperationCallerC Service::create(std::string name, ExecutionEngine* caller) {
00286 return internal::OperationCallerC( getPart(name), name, caller );
00287 }
00288
00289 }