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