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 "SendHandleC.hpp"
00040 #include "../FactoryExceptions.hpp"
00041 #include "DataSourceCommand.hpp"
00042 #include "../Service.hpp"
00043 #include "../Logger.hpp"
00044 #include "Exceptions.hpp"
00045 #include <vector>
00046
00047 namespace RTT {
00048 using namespace detail;
00049
00050
00051 class SendHandleC::E
00052 {
00053 public:
00054 E(base::DataSourceBase::shared_ptr op) : s(), b(), mop(op), orp(0) {}
00055
00056 ~E() {
00057
00058
00059
00060 mopkeeper.reset();
00061 }
00062
00067 internal::DataSource<SendStatus>::shared_ptr s;
00071 internal::AssignableDataSource<bool>::shared_ptr b;
00075 base::DataSourceBase::shared_ptr mop;
00076
00081 struct OperationKeeper
00082 {
00083 DataSource<SendStatus>::shared_ptr ms;
00084 AssignableDataSource<bool>::shared_ptr mb;
00085 bool autocollect;
00086 OperationKeeper(DataSource<SendStatus>::shared_ptr s, AssignableDataSource<bool>::shared_ptr b) : ms(s), mb(b), autocollect(true) {}
00087 ~OperationKeeper() {
00088 if (ms && autocollect) {
00089 mb->set(true);
00090 try {
00091 ms->evaluate();
00092 } catch (std::exception&) {
00093 }
00094 }
00095 }
00096 };
00097
00098 boost::shared_ptr<OperationKeeper> mopkeeper;
00099
00103 OperationInterfacePart* orp;
00104 };
00105
00106
00107
00108 class SendHandleC::D
00109 {
00110 public:
00111 OperationInterfacePart* mofp;
00112 std::string mname;
00113 std::vector<DataSourceBase::shared_ptr> args;
00114 DataSource<SendStatus>::shared_ptr s;
00115 DataSourceBase::shared_ptr msh;
00116 AssignableDataSource<bool>::shared_ptr blocking;
00117
00118 void checkAndCreate() {
00119 Logger::In in("SendHandleC");
00120 if ( mofp ) {
00121 size_t sz = mofp->collectArity();
00122 if ( sz == args.size() ) {
00123
00124 args.insert( args.begin(), msh );
00125
00126 s = boost::dynamic_pointer_cast<DataSource<SendStatus> >( mofp->produceCollect(args, blocking ) );
00127 args.clear();
00128 if ( !s ) {
00129 log(Error) << "Failed to produce collector for "<< mname << " with " << sz << " arguments." << endlog();
00130 return;
00131 }
00132 }
00133 }
00134 }
00135
00136 void newarg(DataSourceBase::shared_ptr na)
00137 {
00138 this->args.push_back( na );
00139 this->checkAndCreate();
00140 }
00141
00142 D( base::DataSourceBase::shared_ptr sh, OperationInterfacePart* ofp, const std::string& name)
00143 : mofp(ofp), mname(name), s(), msh(sh), blocking( new ValueDataSource<bool>(false) )
00144 {
00145 this->checkAndCreate();
00146 }
00147
00148 D(const D& other)
00149 : mofp(other.mofp), mname(other.mname),
00150 args( other.args ), s( other.s ), msh(other.msh), blocking(new ValueDataSource<bool>(false))
00151 {
00152 }
00153
00154 ~D()
00155 {
00156 }
00157
00158 };
00159
00160 SendHandleC::SendHandleC()
00161 : d(0), e( new E(0) )
00162 {
00163 }
00164
00165 SendHandleC::SendHandleC( base::DataSourceBase::shared_ptr op, base::DataSourceBase::shared_ptr sh, OperationInterfacePart* ofp, const std::string& name )
00166 : d( ofp ? new D( sh, ofp, name ) : 0 ), e( new E(op) )
00167 {
00168 if ( d->s ) {
00169 e->s = d->s;
00170 e->b = d->blocking;
00171 e->mopkeeper.reset( new E::OperationKeeper( e->s, e->b) );
00172 delete d;
00173 d = 0;
00174 }
00175 this->e->orp = ofp;
00176 }
00177
00178 SendHandleC::SendHandleC(const SendHandleC& other)
00179 : d( other.d ? new D(*other.d) : 0 ), e( new E(*other.e) )
00180 {
00181 }
00182
00183 SendHandleC& SendHandleC::operator=(const SendHandleC& other)
00184 {
00185 if ( &other == this )
00186 return *this;
00187 delete d;
00188 d = ( other.d ? new D(*other.d) : 0 );
00189 e->s = other.e->s;
00190 e->b = other.e->b;
00191 e->mop = other.e->mop;
00192 e->mopkeeper = other.e->mopkeeper;
00193 e->orp = other.e->orp;
00194 return *this;
00195 }
00196
00197 SendHandleC::~SendHandleC()
00198 {
00199 delete d;
00200 delete e;
00201 }
00202
00203 SendHandleC& SendHandleC::arg( DataSourceBase::shared_ptr a )
00204 {
00205 if (d)
00206 d->newarg( a );
00207 else {
00208 Logger::log() <<Logger::Warning << "Extra argument discarded for SendHandleC."<<Logger::endl;
00209 }
00210 if ( d && d->s ) {
00211 e->s = d->s;
00212 e->b = d->blocking;
00213 e->orp = d->mofp;
00214 e->mopkeeper.reset( new E::OperationKeeper( e->s, e->b) );
00215 delete d;
00216 d = 0;
00217 }
00218 return *this;
00219 }
00220
00221 SendStatus SendHandleC::collect() {
00222 if (e->s) {
00223 e->b->set(true);
00224 e->s->evaluate();
00225 return e->s->value();
00226 }
00227 else {
00228 Logger::log() <<Logger::Error << "collect() called on incomplete SendHandleC."<<Logger::endl;
00229 if (d) {
00230 size_t sz;
00231 sz = d->mofp->collectArity();
00232 Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
00233 Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
00234 }
00235 }
00236 return SendFailure;
00237 }
00238
00239 SendStatus SendHandleC::collectIfDone() {
00240 if (e->s) {
00241 e->b->set(false);
00242
00243 e->s->evaluate();
00244
00245 return e->s->value();
00246 }
00247 else {
00248 Logger::log() <<Logger::Error << "collectIfDone() called on incomplete SendHandleC."<<Logger::endl;
00249 if (d) {
00250 size_t sz;
00251 sz = d->mofp->collectArity();
00252 Logger::log() <<Logger::Error << "Wrong number of arguments provided for method '"+d->mname+"'"<<Logger::nl;
00253 Logger::log() <<Logger::Error << "Expected "<< sz << ", got: " << d->args.size() <<Logger::endl;
00254 }
00255 }
00256 return SendFailure;
00257 }
00258
00259 bool SendHandleC::ready() const
00260 {
00261 return e->s != 0;
00262 }
00263
00264 void SendHandleC::setAutoCollect(bool on_off) {
00265 if (e->mopkeeper)
00266 e->mopkeeper->autocollect = on_off;
00267 }
00268
00269 void SendHandleC::check() {
00270 if (d) {
00271
00272 if (d->mofp)
00273 DataSourceBase::shared_ptr dummy = d->mofp->produceCollect( d->args, d->blocking );
00274 else
00275 throw invalid_handle_exception();
00276 }
00277 }
00278
00279
00280 DataSourceBase::shared_ptr SendHandleC::getSendHandleDataSource() { return e->s; }
00281
00282 OperationInterfacePart* SendHandleC::getOrp() { return e->orp; }
00283 }