$search
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:54:57 CEST 2010 functors_test.cpp 00003 00004 functors_test.cpp - description 00005 ------------------- 00006 begin : Tue September 07 2010 00007 copyright : (C) 2010 The SourceWorks 00008 email : peter@thesourceworks.com 00009 00010 *************************************************************************** 00011 * * 00012 * This program is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU General Public License as published by * 00014 * the Free Software Foundation; either version 2 of the License, or * 00015 * (at your option) any later version. * 00016 * * 00017 ***************************************************************************/ 00018 00019 00020 #include <iostream> 00021 #include <TaskContext.hpp> 00022 #include <OperationCaller.hpp> 00023 #include <Operation.hpp> 00024 #ifdef ORO_REMOTING 00025 #include <internal/RemoteOperationCaller.hpp> 00026 #endif 00027 #include <Service.hpp> 00028 #include <internal/DataSourceGenerator.hpp> 00029 00030 #include "unit.hpp" 00031 #include "operations_fixture.hpp" 00032 00037 BOOST_FIXTURE_TEST_SUITE( FunctorsTestSuite, OperationsFixture ) 00038 00039 BOOST_AUTO_TEST_CASE(testClientThreadFunctor) 00040 { 00041 // Test the produce() method, which maps to call() 00042 00043 std::vector<base::DataSourceBase::shared_ptr> args; 00044 DataSourceBase::shared_ptr dsb = tc->provides("methods")->produce("m0", args, caller->engine()); 00045 DataSource<double>::shared_ptr dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00046 BOOST_CHECK_EQUAL( -1.0, dsd->get()); 00047 00048 args = GenerateDataSource().operator()<int>(1); 00049 dsb = tc->provides("methods")->produce("m1", args, caller->engine()); 00050 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00051 BOOST_CHECK_EQUAL( -2.0, dsd->get()); 00052 00053 args = GenerateDataSource().operator()<int,double>(1, 2.0); 00054 dsb = tc->provides("methods")->produce("m2", args, caller->engine()); 00055 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00056 BOOST_CHECK_EQUAL( -3.0, dsd->get()); 00057 00058 args = GenerateDataSource().operator()<int,double,bool>(1,2.0,true); 00059 dsb = tc->provides("methods")->produce("m3", args, caller->engine()); 00060 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00061 BOOST_CHECK_EQUAL( -4.0, dsd->get()); 00062 00063 args = GenerateDataSource().operator()<int,double,bool,std::string>(1,2.0,true,"hello"); 00064 dsb = tc->provides("methods")->produce("m4", args, caller->engine()); 00065 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00066 BOOST_CHECK_EQUAL( -5.0, dsd->get()); 00067 00068 args = GenerateDataSource().operator()<int,double,bool,std::string,float>(1,2.0,true,"hello", 5.0f); 00069 dsb = tc->provides("methods")->produce("m5", args, caller->engine()); 00070 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00071 BOOST_CHECK_EQUAL( -6.0, dsd->get()); 00072 00073 args = GenerateDataSource().operator()<int,double,bool,std::string,float>(1,2.0,true,"hello", 5.0f, 'a'); 00074 dsb = tc->provides("methods")->produce("m6", args, caller->engine()); 00075 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00076 BOOST_CHECK_EQUAL( -7.0, dsd->get()); 00077 00078 args = GenerateDataSource().operator()<int,double,bool,std::string,float>(1,2.0,true,"hello", 5.0f, 'a', (unsigned int)7); 00079 dsb = tc->provides("methods")->produce("m7", args, caller->engine()); 00080 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00081 BOOST_CHECK_EQUAL( -8.0, dsd->get()); 00082 00083 double d = 10.0; 00084 args = GenerateDataSource().operator()<double&>(d); 00085 dsb = tc->provides("methods")->produce("m1r", args, caller->engine()); 00086 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00087 BOOST_CHECK_EQUAL( 20.0, dsd->get()); // 2*a 00088 BOOST_CHECK_EQUAL( 20.0, d ); // 2* &a 00089 } 00090 00091 BOOST_AUTO_TEST_CASE(testOwnThreadOperationCallerCall) 00092 { 00093 // Test the produce() method, which maps to call() for OwnThread case: 00094 00095 std::vector<base::DataSourceBase::shared_ptr> args; 00096 DataSourceBase::shared_ptr dsb = tc->provides("methods")->produce("o0", args, caller->engine()); 00097 DataSource<double>::shared_ptr dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00098 BOOST_CHECK_EQUAL( -1.0, dsd->get()); 00099 00100 args = GenerateDataSource().operator()<int>(1); 00101 dsb = tc->provides("methods")->produce("o1", args, caller->engine()); 00102 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00103 BOOST_CHECK_EQUAL( -2.0, dsd->get()); 00104 00105 args = GenerateDataSource().operator()<int,double>(1, 2.0); 00106 dsb = tc->provides("methods")->produce("o2", args, caller->engine()); 00107 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00108 BOOST_CHECK_EQUAL( -3.0, dsd->get()); 00109 00110 args = GenerateDataSource().operator()<int,double,bool>(1,2.0,true); 00111 dsb = tc->provides("methods")->produce("o3", args, caller->engine()); 00112 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00113 BOOST_CHECK_EQUAL( -4.0, dsd->get()); 00114 00115 args = GenerateDataSource().operator()<int,double,bool,std::string>(1,2.0,true,"hello"); 00116 dsb = tc->provides("methods")->produce("o4", args, caller->engine()); 00117 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00118 BOOST_CHECK_EQUAL( -5.0, dsd->get()); 00119 00120 args = GenerateDataSource().operator()<int,double,bool,std::string,float>(1,2.0,true,"hello", 5.0f); 00121 dsb = tc->provides("methods")->produce("o5", args, caller->engine()); 00122 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00123 BOOST_CHECK_EQUAL( -6.0, dsd->get()); 00124 00125 args = GenerateDataSource().operator()<int,double,bool,std::string,float,char>(1,2.0,true,"hello", 5.0f, 'a'); 00126 dsb = tc->provides("methods")->produce("o6", args, caller->engine()); 00127 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00128 BOOST_CHECK_EQUAL( -7.0, dsd->get()); 00129 00130 args = GenerateDataSource().operator()<int,double,bool,std::string,float,char,unsigned int>(1,2.0,true,"hello", 5.0f, 'a', (unsigned int)7); 00131 dsb = tc->provides("methods")->produce("o7", args, caller->engine()); 00132 dsd = dynamic_pointer_cast<DataSource<double> >(dsb); 00133 BOOST_CHECK_EQUAL( -8.0, dsd->get()); 00134 } 00135 00136 00137 BOOST_AUTO_TEST_CASE(testOwnThreadOperationCallerSend) 00138 { 00139 BOOST_REQUIRE( tc->isRunning() ); 00140 BOOST_REQUIRE( caller->isRunning() ); 00141 SendHandle<double(void)> h0; 00142 SendHandle<double(int)> h1; 00143 SendHandle<double(int,double)> h2; 00144 SendHandle<double(int,double,bool)> h3; 00145 SendHandle<double(int,double,bool,std::string)> h4; 00146 SendHandle<double(int,double,bool,std::string,float)> h5; 00147 SendHandle<double(int,double,bool,std::string,float,char)> h6; 00148 SendHandle<double(int,double,bool,std::string,float,char,unsigned int)> h7; 00149 SendHandle<double(double&)> h1r; 00150 00151 // Test the produceSend() and produceHandle() methods, which maps to send() for OwnThread case: 00152 00153 std::vector<base::DataSourceBase::shared_ptr> args; 00154 ValueDataSource<double>::shared_ptr dsr = new ValueDataSource<double>(); 00155 DataSourceBase::shared_ptr dsb; // send 00156 DataSourceBase::shared_ptr dsh; // handle 00157 DataSourceBase::shared_ptr dsc; // collect 00158 ActionInterface* update; 00159 00160 // Get send and handle functors: 00161 dsb = tc->provides("methods")->produceSend("o0", args, caller->engine()); 00162 dsh= tc->provides("methods")->produceHandle("o0"); 00163 args.clear(); 00164 args.push_back( dsh ); 00165 args.push_back( dsr ); 00166 DataSourceBase::shared_ptr dsc0 = tc->provides("methods")->produceCollect("o0",args,new ValueDataSource<bool>(true)); 00167 00168 // Assign the handle of produceSend to the one of produceHandle: 00169 update = dsh->updateAction( dsb.get() ); 00170 update->readArguments(); 00171 update->execute(); 00172 delete update; 00173 00174 // get the handle: 00175 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(void)> >* >( dsh.get() ) ); 00176 h0 = dynamic_cast<DataSource<SendHandle<double(void)> >* >( dsh.get() )->get(); 00177 BOOST_CHECK( h0.ready() ); 00178 00179 args = GenerateDataSource().operator()<int>(1); 00180 // Get send and handle functors: 00181 dsb = tc->provides("methods")->produceSend("o1", args, caller->engine()); 00182 dsh= tc->provides("methods")->produceHandle("o1"); 00183 args.clear(); 00184 args.push_back( dsh ); 00185 args.push_back( dsr ); 00186 DataSourceBase::shared_ptr dsc1 = tc->provides("methods")->produceCollect("o1",args, new ValueDataSource<bool>(true)); 00187 00188 // Assign the handle of produceSend to the one of produceHandle: 00189 update = dsh->updateAction( dsb.get() ); 00190 update->readArguments(); 00191 update->execute(); 00192 delete update; 00193 00194 // get the handle: 00195 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int)> >* >( dsh.get() ) ); 00196 h1 = dynamic_cast<DataSource<SendHandle<double(int)> >* >( dsh.get() )->get(); 00197 BOOST_CHECK( h1.ready() ); 00198 00199 00200 args = GenerateDataSource().operator()<int,double>(1, 2.0); 00201 // Get send and handle functors: 00202 dsb = tc->provides("methods")->produceSend("o2", args, caller->engine()); 00203 dsh= tc->provides("methods")->produceHandle("o2"); 00204 00205 // Assign the handle of produceSend to the one of produceHandle: 00206 update = dsh->updateAction( dsb.get() ); 00207 update->readArguments(); 00208 update->execute(); 00209 delete update; 00210 00211 // get the handle: 00212 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int,double)> >* >( dsh.get() ) ); 00213 h2 = dynamic_cast<DataSource<SendHandle<double(int,double)> >* >( dsh.get() )->get(); 00214 BOOST_CHECK( h2.ready() ); 00215 00216 args = GenerateDataSource().operator()<int,double,bool>(1,2.0,true); 00217 // Get send and handle functors: 00218 dsb = tc->provides("methods")->produceSend("o3", args, caller->engine()); 00219 dsh= tc->provides("methods")->produceHandle("o3"); 00220 00221 // Assign the handle of produceSend to the one of produceHandle: 00222 update = dsh->updateAction( dsb.get() ); 00223 update->readArguments(); 00224 update->execute(); 00225 delete update; 00226 // get the handle: 00227 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int,double,bool)> >* >( dsh.get() ) ); 00228 h3 = dynamic_cast<DataSource<SendHandle<double(int,double,bool)> >* >( dsh.get() )->get(); 00229 BOOST_CHECK( h3.ready() ); 00230 00231 args = GenerateDataSource().operator()<int,double,bool,std::string>(1,2.0,true,"hello"); 00232 // Get send and handle functors: 00233 dsb = tc->provides("methods")->produceSend("o4", args, caller->engine()); 00234 dsh= tc->provides("methods")->produceHandle("o4"); 00235 // Assign the handle of produceSend to the one of produceHandle: 00236 update = dsh->updateAction( dsb.get() ); 00237 update->readArguments(); 00238 update->execute(); 00239 delete update; 00240 // get the handle: 00241 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string)> >* >( dsh.get() ) ); 00242 h4 = dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string)> >* >( dsh.get() )->get(); 00243 BOOST_CHECK( h4.ready() ); 00244 00245 args = GenerateDataSource().operator()<int,double,bool,std::string,float>(1,2.0,true,"hello",5.0f); 00246 // Get send and handle functors: 00247 dsb = tc->provides("methods")->produceSend("o5", args, caller->engine()); 00248 dsh= tc->provides("methods")->produceHandle("o5"); 00249 // Assign the handle of produceSend to the one of produceHandle: 00250 update = dsh->updateAction( dsb.get() ); 00251 update->readArguments(); 00252 update->execute(); 00253 delete update; 00254 // get the handle: 00255 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string,float)> >* >( dsh.get() ) ); 00256 h5 = dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string,float)> >* >( dsh.get() )->get(); 00257 BOOST_CHECK( h5.ready() ); 00258 00259 args = GenerateDataSource().operator()<int,double,bool,std::string,float,char>(1,2.0,true,"hello",5.0f,'a'); 00260 // Get send and handle functors: 00261 dsb = tc->provides("methods")->produceSend("o6", args, caller->engine()); 00262 dsh= tc->provides("methods")->produceHandle("o6"); 00263 // Assign the handle of produceSend to the one of produceHandle: 00264 update = dsh->updateAction( dsb.get() ); 00265 update->readArguments(); 00266 update->execute(); 00267 delete update; 00268 // get the handle: 00269 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string,float,char)> >* >( dsh.get() ) ); 00270 h6 = dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string,float,char)> >* >( dsh.get() )->get(); 00271 BOOST_CHECK( h6.ready() ); 00272 00273 args = GenerateDataSource().operator()<int,double,bool,std::string,float,char,unsigned int>(1,2.0,true,"hello",5.0f,'a',(unsigned int)7); 00274 // Get send and handle functors: 00275 dsb = tc->provides("methods")->produceSend("o7", args, caller->engine()); 00276 dsh= tc->provides("methods")->produceHandle("o7"); 00277 // Assign the handle of produceSend to the one of produceHandle: 00278 update = dsh->updateAction( dsb.get() ); 00279 update->readArguments(); 00280 update->execute(); 00281 delete update; 00282 // get the handle: 00283 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string,float,char,unsigned int)> >* >( dsh.get() ) ); 00284 h7 = dynamic_cast<DataSource<SendHandle<double(int,double,bool,std::string,float,char,unsigned int)> >* >( dsh.get() )->get(); 00285 BOOST_CHECK( h7.ready() ); 00286 00287 00288 double d = 10.0; 00289 args = GenerateDataSource().operator()<double&>(d); 00290 dsb = tc->provides("methods")->produceSend("o1r", args, caller->engine()); 00291 dsh = tc->provides("methods")->produceHandle("o1r"); 00292 // Assign the handle of produceSend to the one of produceHandle: 00293 update = dsh->updateAction( dsb.get() ); 00294 update->readArguments(); 00295 update->execute(); 00296 delete update; 00297 // get the handle: 00298 BOOST_REQUIRE( dynamic_cast<DataSource<SendHandle<double(double&)> >* >( dsh.get() ) ); 00299 h1r = dynamic_cast<DataSource<SendHandle<double(double&)> >* >( dsh.get() )->get(); 00300 BOOST_CHECK( h1r.ready() ); 00301 00302 // Now check all receptions all-in-once: 00303 double retn=0; 00304 double rarg=0; 00305 dsc0->evaluate(); 00306 BOOST_CHECK_EQUAL( dsr->get(), -1.0 ); 00307 BOOST_CHECK_EQUAL( SendSuccess, h0.collect(retn) ); 00308 BOOST_CHECK_EQUAL( retn, -1.0 ); 00309 BOOST_CHECK_EQUAL( SendSuccess, h1.collect(retn) ); 00310 BOOST_CHECK_EQUAL( retn, -2.0 ); 00311 BOOST_CHECK_EQUAL( SendSuccess, h2.collect(retn) ); 00312 BOOST_CHECK_EQUAL( retn, -3.0 ); 00313 BOOST_CHECK_EQUAL( SendSuccess, h3.collect(retn) ); 00314 BOOST_CHECK_EQUAL( retn, -4.0 ); 00315 BOOST_CHECK_EQUAL( SendSuccess, h4.collect(retn) ); 00316 BOOST_CHECK_EQUAL( retn, -5.0 ); 00317 BOOST_CHECK_EQUAL( SendSuccess, h5.collect(retn) ); 00318 BOOST_CHECK_EQUAL( retn, -6.0 ); 00319 BOOST_CHECK_EQUAL( SendSuccess, h6.collect(retn) ); 00320 BOOST_CHECK_EQUAL( retn, -7.0 ); 00321 BOOST_CHECK_EQUAL( SendSuccess, h7.collect(retn) ); 00322 BOOST_CHECK_EQUAL( retn, -8.0 ); 00323 BOOST_CHECK_EQUAL( SendSuccess, h1r.collect(retn, rarg) ); 00324 BOOST_CHECK_EQUAL( retn, 20.0 ); 00325 BOOST_CHECK_EQUAL( rarg, 20.0 ); 00326 00327 retn = rarg = 0; 00328 // collectIfDone will certainly succeed after collect 00329 BOOST_CHECK_EQUAL( SendSuccess, h0.collectIfDone(retn) ); 00330 BOOST_CHECK_EQUAL( retn, -1.0 ); 00331 BOOST_CHECK_EQUAL( SendSuccess, h1.collectIfDone(retn) ); 00332 BOOST_CHECK_EQUAL( retn, -2.0 ); 00333 BOOST_CHECK_EQUAL( SendSuccess, h2.collectIfDone(retn) ); 00334 BOOST_CHECK_EQUAL( retn, -3.0 ); 00335 BOOST_CHECK_EQUAL( SendSuccess, h3.collectIfDone(retn) ); 00336 BOOST_CHECK_EQUAL( retn, -4.0 ); 00337 BOOST_CHECK_EQUAL( SendSuccess, h4.collectIfDone(retn) ); 00338 BOOST_CHECK_EQUAL( retn, -5.0 ); 00339 BOOST_CHECK_EQUAL( SendSuccess, h5.collectIfDone(retn) ); 00340 BOOST_CHECK_EQUAL( retn, -6.0 ); 00341 BOOST_CHECK_EQUAL( SendSuccess, h6.collectIfDone(retn) ); 00342 BOOST_CHECK_EQUAL( retn, -7.0 ); 00343 BOOST_CHECK_EQUAL( SendSuccess, h7.collectIfDone(retn) ); 00344 BOOST_CHECK_EQUAL( retn, -8.0 ); 00345 BOOST_CHECK_EQUAL( SendSuccess, h1r.collectIfDone(retn,rarg) ); 00346 BOOST_CHECK_EQUAL( retn, 20.0 ); 00347 BOOST_CHECK_EQUAL( rarg, 20.0 ); 00348 00349 // the return value api. 00350 BOOST_CHECK_EQUAL( -1.0, h0.ret() ); 00351 BOOST_CHECK_EQUAL( -2.0, h1.ret(1) ); 00352 BOOST_CHECK_EQUAL( -3.0, h2.ret(1, 2.0) ); 00353 BOOST_CHECK_EQUAL( -4.0, h3.ret(1, 2.0, true) ); 00354 BOOST_CHECK_EQUAL( -5.0, h4.ret(1, 2.0, true,"hello") ); 00355 BOOST_CHECK_EQUAL( -6.0, h5.ret(1, 2.0, true,"hello", 5.0f) ); 00356 BOOST_CHECK_EQUAL( -7.0, h6.ret(1, 2.0, true,"hello", 5.0f, 'a') ); 00357 BOOST_CHECK_EQUAL( -8.0, h7.ret(1, 2.0, true,"hello", 5.0f, 'a', (unsigned int)7) ); 00358 00359 BOOST_CHECK_EQUAL( -2.0, h1.ret() ); 00360 BOOST_CHECK_EQUAL( -3.0, h2.ret() ); 00361 BOOST_CHECK_EQUAL( -4.0, h3.ret() ); 00362 BOOST_CHECK_EQUAL( -5.0, h4.ret() ); 00363 BOOST_CHECK_EQUAL( -6.0, h5.ret() ); 00364 BOOST_CHECK_EQUAL( -7.0, h6.ret() ); 00365 BOOST_CHECK_EQUAL( -8.0, h7.ret() ); 00366 BOOST_CHECK_EQUAL( 20.0, h1r.ret() ); 00367 } 00368 #ifdef ORO_REMOTING_OLD 00369 00370 BOOST_AUTO_TEST_CASE(testOperationCallerFactory) 00371 { 00372 // Test the addition of 'simple' methods to the operation interface, 00373 // and retrieving it back in a new OperationCaller object. 00374 00375 Operation<double(void)> m0("m0"); 00376 m0.calls(&FunctorsTest::m0, this); 00377 Operation<double(int)> m1("m1"); 00378 m1.calls(&FunctorsTest::m1, this); 00379 Operation<double(int,double)> m2("m2"); 00380 m2.calls(&FunctorsTest::m2, this); 00381 00382 Service to("task"); 00383 00384 BOOST_CHECK( !to.addOperation(m0).ready() ); 00385 to.setOwner(tc); 00386 BOOST_CHECK( to.addOperation(m0).ready() ); 00387 BOOST_CHECK( to.addOperation(m0).ready() ); 00388 BOOST_CHECK( to.addOperation(m1).ready() ); 00389 BOOST_CHECK( to.addOperation(m2).ready() ); 00390 00391 // test constructor 00392 OperationCaller<double(void)> mm0 = to.getOperation<double(void)>("m0"); 00393 BOOST_CHECK( mm0.getOperationCallerImpl() ); 00394 BOOST_CHECK( mm0.ready() ); 00395 00396 // test operator=() 00397 OperationCaller<double(int)> mm1; 00398 mm1 = to.getOperation<double(int)>("m1"); 00399 BOOST_CHECK( mm1.getOperationCallerImpl() ); 00400 BOOST_CHECK( mm1.ready() ); 00401 00402 OperationCaller<double(int,double)> mm2 = to.getOperation<double(int,double)>("m2"); 00403 BOOST_CHECK( mm2.getOperationCallerImpl() ); 00404 BOOST_CHECK( mm2.ready() ); 00405 00406 // execute methods and check status: 00407 BOOST_CHECK_EQUAL( -1.0, mm0() ); 00408 00409 BOOST_CHECK_EQUAL( -2.0, mm1(1) ); 00410 BOOST_CHECK_EQUAL( -3.0, mm2(1, 2.0) ); 00411 00412 // test error cases: 00413 // Add uninitialised op: 00414 Operation<void(void)> ovoid("voidm"); 00415 BOOST_CHECK(to.addOperation( ovoid ).ready() == false); 00416 ovoid = Operation<void(void)>("voidm"); 00417 BOOST_CHECK(to.addOperation( ovoid ).ready() == false); 00418 00419 // wrong type 1: 00420 OperationCaller<void(void)> mvoid; 00421 mvoid = to.getOperation<void(void)>("m1"); 00422 BOOST_CHECK( mvoid.ready() == false ); 00423 // wrong type 2: 00424 mvoid = to.getOperation<void(bool)>("m1"); 00425 // wrong type 3: 00426 mvoid = to.getOperation<double(void)>("m0"); 00427 BOOST_CHECK( mvoid.ready() == false ); 00428 // non existing 00429 mvoid = to.getOperation<void(void)>("voidm"); 00430 BOOST_CHECK( mvoid.ready() == false ); 00431 00432 // this line may not crash: 00433 mvoid(); 00434 00435 } 00436 00437 BOOST_AUTO_TEST_CASE(testCROperationCaller) 00438 { 00439 this->ret = -3.3; 00440 00441 OperationCaller<double&(void)> m0r("m0r", &FunctorsTest::m0r, this); 00442 OperationCaller<const double&(void)> m0cr("m0cr", &FunctorsTest::m0cr, this); 00443 00444 OperationCaller<double(double&)> m1r("m1r", &FunctorsTest::m1r, this); 00445 OperationCaller<double(const double&)> m1cr("m1cr", &FunctorsTest::m1cr, this); 00446 00447 BOOST_CHECK_EQUAL( -3.3, m0r() ); 00448 BOOST_CHECK_EQUAL( -3.3, m0cr() ); 00449 00450 double value = 5.3; 00451 BOOST_CHECK_EQUAL( 5.3*2, m1r(value) ); 00452 BOOST_CHECK_EQUAL( 5.3*2, value ); 00453 BOOST_CHECK_EQUAL( 5.3, m1cr(5.3) ); 00454 } 00455 00456 BOOST_AUTO_TEST_CASE(testOperationCallerFromDS) 00457 { 00458 Service to("task"); 00459 00460 OperationCaller<double(void)> m0("m0", &FunctorsTest::m0, this); 00461 OperationCaller<double(int)> m1("m1", &FunctorsTest::m1, this); 00462 OperationCaller<double(int,double)> m2("m2", &FunctorsTest::m2, this); 00463 OperationCaller<double(int,double,bool)> m3("m3", &FunctorsTest::m3, this); 00464 OperationCaller<double(int,double,bool,std::string)> m4("m4", &FunctorsTest::m4, this); 00465 00466 to.addOperation( &m0, "desc"); 00467 to.addOperation( &m1, "desc", "a1", "d1"); 00468 to.addOperation( &m2, "desc", "a1", "d1", "a2","d2"); 00469 to.addOperation( &m3, "desc", "a1", "d1", "a2","d2","a3","d3"); 00470 to.addOperation( &m4, "desc", "a1", "d1", "a2","d2","a3","d3", "a4","d4"); 00471 00472 double ret; 00473 OperationCallerC mc0( to.methods(), "m0"); 00474 mc0.ret(ret); 00475 OperationCallerC mc1( to.methods(), "m1"); 00476 mc1.argC(1).ret(ret); 00477 OperationCallerC mc2( to.methods(), "m2"); 00478 mc2.argC(1).argC(2.0).ret(ret); 00479 OperationCallerC mc3( to.methods(), "m3"); 00480 mc3.argC(1).argC(2.0).argC(false).ret(ret); 00481 OperationCallerC mc4( to.methods(), "m4"); 00482 mc4.argC(1).argC(2.0).argC(false).argC(std::string("hello")).ret(ret); 00483 00484 BOOST_CHECK( mc0.execute() ); 00485 BOOST_CHECK_EQUAL(-1.0, ret); 00486 BOOST_CHECK( mc1.execute() ); 00487 BOOST_CHECK_EQUAL(-2.0, ret); 00488 BOOST_CHECK( mc2.execute() ); 00489 BOOST_CHECK_EQUAL(-3.0, ret); 00490 BOOST_CHECK( mc3.execute() ); 00491 BOOST_CHECK_EQUAL(-4.0, ret); 00492 BOOST_CHECK( mc4.execute() ); 00493 BOOST_CHECK_EQUAL(-5.0, ret); 00494 } 00495 00496 BOOST_AUTO_TEST_CASE(testDSOperationCaller) 00497 { 00498 Service to("task", tc); 00499 00500 // A method of which the first argument type is a pointer to the object 00501 // on which it must be invoked. The pointer is internally stored as a weak_ptr, 00502 // thus the object must be stored in a shared_ptr, in a DataSource. Scripting 00503 // requires this for copying state machines. 00504 00505 Operation<double(FunctorsTest*)> meth0("m0"); 00506 meth0.calls( boost::bind(&FunctorsTest::m0, _1)); 00507 00508 //method_ds("m0", &FunctorsTest::m0); 00509 00510 Operation<double(FunctorsTest*,int)> meth1("m1"); 00511 meth1.calls(boost::bind(&FunctorsTest::m1, _1,_2)); 00512 00513 //method_ds("m1", &FunctorsTest::m1); 00514 //method_ds("ms",&FunctorsTest::comstr ); 00515 00516 boost::shared_ptr<FunctorsTest> ptr( new FunctorsTest() ); 00517 ValueDataSource<boost::weak_ptr<FunctorsTest> >::shared_ptr wp = new ValueDataSource<boost::weak_ptr<FunctorsTest> >( ptr ); 00518 BOOST_CHECK( to.addOperationDS( wp.get(), meth0).doc("desc" ).ready() ); 00519 BOOST_CHECK( to.addOperationDS( wp.get(), meth1).doc("desc").arg("a1", "d1" ).ready() ); 00520 00521 // this actually works ! the method will detect the deleted pointer. 00522 //ptr.reset(); 00523 00524 double ret; 00525 OperationCallerC c0 = to.create("m0").ret(ret); 00526 BOOST_CHECK( c0.execute() ); 00527 BOOST_CHECK_EQUAL( -1.0, ret ); 00528 OperationCallerC c1 = to.create("m1").argC(1).ret(ret); 00529 BOOST_CHECK( c1.execute() ); 00530 BOOST_CHECK_EQUAL( -2.0, ret ); 00531 00532 } 00533 #endif // defined(ORO_REMOTING) 00534 00535 BOOST_AUTO_TEST_SUITE_END()