From ca0f70501f3979c45b779db095343672cdb94dd1 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 17 Feb 2017 20:38:58 +0100 Subject: [PATCH] corba: add fake operation loadPlugin to every OperationInterface Signed-off-by: Johannes Meyer --- rtt/internal/FusedFunctorDataSource.hpp | 1 + rtt/transports/corba/OperationInterfaceI.cpp | 108 ++++++++++--------- rtt/transports/corba/OperationInterfaceI.h | 8 ++ 3 files changed, 69 insertions(+), 48 deletions(-) diff --git a/rtt/internal/FusedFunctorDataSource.hpp b/rtt/internal/FusedFunctorDataSource.hpp index 4e7a1b5fc..fad59a9e1 100644 --- a/rtt/internal/FusedFunctorDataSource.hpp +++ b/rtt/internal/FusedFunctorDataSource.hpp @@ -45,6 +45,7 @@ #include "BindStorage.hpp" #include "../ExecutionEngine.hpp" #include "../os/oro_allocator.hpp" +#include "UnMember.hpp" #include #include #include diff --git a/rtt/transports/corba/OperationInterfaceI.cpp b/rtt/transports/corba/OperationInterfaceI.cpp index aa847029c..98d931491 100644 --- a/rtt/transports/corba/OperationInterfaceI.cpp +++ b/rtt/transports/corba/OperationInterfaceI.cpp @@ -75,6 +75,7 @@ #include "../../internal/SendHandleC.hpp" #include "../../Logger.hpp" #include "../../internal/GlobalEngine.hpp" +#include "../../plugin/PluginLoader.hpp" using namespace RTT; using namespace RTT::detail; @@ -214,8 +215,11 @@ void RTT_corba_CSendHandle_i::dispose ( // Implementation skeleton constructor RTT_corba_COperationInterface_i::RTT_corba_COperationInterface_i (OperationInterface* gmf, PortableServer::POA_ptr the_poa) - :mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa)) + : mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa)), + loadPluginOperation("loadPlugin", &RTT_corba_COperationInterface_i::loadPlugin, this), + loadPluginOperationPart(&loadPluginOperation) { + loadPluginOperation.doc("Loads a RTT plugin.").arg("plugin_path", "The path to the shared library containing the plugin."); } PortableServer::POA_ptr RTT_corba_COperationInterface_i::_default_POA() @@ -235,6 +239,7 @@ ::RTT::corba::COperationInterface::COperationList * RTT_corba_COperationInterfac RTT::corba::COperationInterface::COperationList_var rlist = new RTT::corba::COperationInterface::COperationList(); vector flist = mfact->getNames(); + flist.push_back(loadPluginOperationPart.getName()); rlist->length( flist.size() ); size_t drops=0; for (size_t i=0; i != flist.size(); ++i) @@ -251,10 +256,9 @@ ::RTT::corba::CDescriptions * RTT_corba_COperationInterface_i::getArguments ( const char * operation) { CDescriptions_var ret = new CDescriptions(); - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation))) - throw ::RTT::corba::CNoSuchNameException( operation ); + OperationInterfacePart* mofp = findOperation(operation); // operation found, convert args: - OperationInterface::Descriptions args = mfact->getArgumentList( string(operation) ); + OperationInterface::Descriptions args = mofp->getArgumentList(); ret->length( args.size() ); for (size_t i =0; i != args.size(); ++i) { ret[i].name = CORBA::string_dup( args[i].name.c_str() ); @@ -267,82 +271,75 @@ ::RTT::corba::CDescriptions * RTT_corba_COperationInterface_i::getArguments ( char * RTT_corba_COperationInterface_i::getResultType ( const char * operation) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); - return CORBA::string_dup( mfact->getResultType( string(operation) ).c_str() ); + OperationInterfacePart* mofp = findOperation(operation); + return CORBA::string_dup( mofp->resultType().c_str() ); } char* RTT_corba_COperationInterface_i::getArgumentType( const char* operation, CORBA::UShort nbr) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); - if ( nbr > mfact->getPart(operation)->arity() ) - throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->arity() ); - return CORBA::string_dup( mfact->getPart( operation )->getArgumentType(nbr)->getTypeName().c_str() ); + OperationInterfacePart* mofp = findOperation(operation); + if ( nbr > mofp->arity() ) + throw ::RTT::corba::CWrongArgumentException( nbr, mofp->arity() ); + return CORBA::string_dup( mofp->getArgumentType(nbr)->getTypeName().c_str() ); } char* RTT_corba_COperationInterface_i::getCollectType( const char* operation, CORBA::UShort nbr) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); - if ( nbr > mfact->getPart(operation)->collectArity() ) - throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->collectArity() ); - return CORBA::string_dup( mfact->getPart( operation )->getCollectType(nbr)->getTypeName().c_str() ); + OperationInterfacePart* mofp = findOperation(operation); + if ( nbr > mofp->collectArity() ) + throw ::RTT::corba::CWrongArgumentException( nbr, mofp->collectArity() ); + return CORBA::string_dup( mofp->getCollectType(nbr)->getTypeName().c_str() ); } ::CORBA::UShort RTT_corba_COperationInterface_i::getArity ( const char * operation) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); - return mfact->getPart(operation)->arity(); + OperationInterfacePart* mofp = findOperation(operation); + return mofp->arity(); } ::CORBA::UShort RTT_corba_COperationInterface_i::getCollectArity ( const char * operation) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); - return mfact->getPart(operation)->collectArity(); + OperationInterfacePart* mofp = findOperation(operation); + return mofp->collectArity(); } char * RTT_corba_COperationInterface_i::getDescription ( const char * operation) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); - return CORBA::string_dup( mfact->getDescription( string(operation) ).c_str() ); + OperationInterfacePart* mofp = findOperation(operation); + return CORBA::string_dup( mofp->description().c_str() ); } void RTT_corba_COperationInterface_i::checkOperation ( const char * operation, const ::RTT::corba::CAnyArguments & args) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); + OperationInterfacePart* mofp = findOperation(operation); + try { - OperationInterfacePart* mofp = mfact->getPart(operation); OperationCallerC mc(mofp, operation, internal::GlobalEngine::Instance()); for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) { const TypeInfo* ti = mofp->getArgumentType(i+1); assert(ti); CorbaTypeTransporter* ctt = dynamic_cast (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); if (ctt) { - DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]); - if (ds) - mc.arg(ds); - else { - log(Error) << "Registered transport for type "<< ti->getTypeName() - << " could not create data source from Any (argument "<< i+1 - <<"): calling operation '"<< operation <<"' will fail." <createDataSource(&args[i]); + if (ds) + mc.arg(ds); + else { + log(Error) << "Registered transport for type "<< ti->getTypeName() + << " could not create data source from Any (argument "<< i+1 + <<"): calling operation '"<< operation <<"' will fail." <getTypeName()); + throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName()); } } mc.check(); @@ -361,14 +358,14 @@ ::CORBA::Any * RTT_corba_COperationInterface_i::callOperation ( const char * operation, ::RTT::corba::CAnyArguments & args) { - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); + OperationInterfacePart* mofp = findOperation(operation); + // convert Corba args to C++ args. try { - OperationCallerC orig(mfact->getPart(operation), operation, internal::GlobalEngine::Instance()); + OperationCallerC orig(mofp, operation, internal::GlobalEngine::Instance()); vector results; for (size_t i =0; i != args.length(); ++i) { - const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); + const TypeInfo* ti = mofp->getArgumentType( i + 1); CorbaTypeTransporter* ctt = dynamic_cast ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); // we need to store the results for returning them to caller (args is inout!) after the call() results.push_back( ctt->createDataSource( &args[i] ) ); @@ -391,7 +388,7 @@ ::CORBA::Any * RTT_corba_COperationInterface_i::callOperation ( // Return results into args: for (size_t i =0; i != args.length(); ++i) { - const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); + const TypeInfo* ti = mofp->getArgumentType( i + 1); CorbaTypeTransporter* ctta = dynamic_cast ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); ctta->updateAny(results[i], args[i]); } @@ -418,13 +415,13 @@ ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation ( const ::RTT::corba::CAnyArguments & args) { // This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part. - if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) - throw ::RTT::corba::CNoSuchNameException( operation ); + OperationInterfacePart* mofp = findOperation(operation); + // convert Corba args to C++ args. try { - OperationCallerC orig(mfact->getPart(operation), operation, internal::GlobalEngine::Instance()); + OperationCallerC orig(mofp, operation, internal::GlobalEngine::Instance()); for (size_t i =0; i != args.length(); ++i) { - const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); + const TypeInfo* ti = mofp->getArgumentType( i + 1); CorbaTypeTransporter* ctt = dynamic_cast ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); orig.arg( ctt->createDataSource( &args[i] )); } @@ -433,7 +430,7 @@ ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation ( // we may not destroy the SendHandle, before the operation completes: resulthandle.setAutoCollect(true); // our resulthandle copy makes sure that the resulthandle can return. - RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mfact->getPart(operation) ); + RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mofp ); CSendHandle_var ret = ret_i->_this(); ret_i->_remove_ref(); // if POA drops this, it gets cleaned up. return ret._retn(); @@ -451,3 +448,18 @@ ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation ( } return CSendHandle::_nil(); } + +RTT::OperationInterfacePart *RTT_corba_COperationInterface_i::findOperation( const char *operation ) +{ + string operation_str(operation); + OperationInterfacePart* mofp = mfact->getPart(operation_str); + if ( !mofp && (operation_str == "loadPlugin") ) + mofp = &loadPluginOperationPart; + if ( !mofp || mfact->isSynchronous(operation_str) ) + throw ::RTT::corba::CNoSuchNameException( operation ); + return mofp; +} + +bool RTT_corba_COperationInterface_i::loadPlugin(const string &pluginPath) { + return RTT::plugin::PluginLoader::Instance()->loadPlugin(pluginPath, ""); +} diff --git a/rtt/transports/corba/OperationInterfaceI.h b/rtt/transports/corba/OperationInterfaceI.h index 35f878b49..c83aed671 100644 --- a/rtt/transports/corba/OperationInterfaceI.h +++ b/rtt/transports/corba/OperationInterfaceI.h @@ -77,6 +77,7 @@ #endif #include "../../OperationInterface.hpp" #include "../../internal/SendHandleC.hpp" +#include "../../internal/OperationInterfacePartFused.hpp" #if !defined (ACE_LACKS_PRAGMA_ONCE) #pragma once @@ -125,6 +126,9 @@ class RTT_corba_COperationInterface_i { RTT::OperationInterface* mfact; PortableServer::POA_var mpoa; + RTT::Operation loadPluginOperation; + RTT::internal::OperationInterfacePartFused loadPluginOperationPart; + public: //Constructor RTT_corba_COperationInterface_i(RTT::OperationInterface* mfact, PortableServer::POA_ptr the_poa); @@ -180,6 +184,10 @@ class RTT_corba_COperationInterface_i ::RTT::corba::CSendHandle_ptr sendOperation ( const char * operation, const ::RTT::corba::CAnyArguments & args); + + private: + RTT::OperationInterfacePart *findOperation ( const char *operation ); + bool loadPlugin ( const std::string& pluginPath ); };