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