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