From 5b0be76430459e29c1e57d4c9f55be193ff8c05d Mon Sep 17 00:00:00 2001 From: ressac Date: Sun, 21 Nov 2010 15:13:11 +0100 Subject: [PATCH] New service architecture. Service now inherit of a base class ServiceInterface. The same thing apply for ServiceRequester. --- rtt/DataFlowInterface.hpp | 26 ++++- rtt/Service.cpp | 96 ++----------- rtt/Service.hpp | 139 ++++-------------- rtt/ServiceInterface.cpp | 143 +++++++++++++++++++ rtt/ServiceInterface.hpp | 210 ++++++++++++++++++++++++++++ rtt/ServiceRequester.cpp | 44 +++---- rtt/ServiceRequester.hpp | 68 +++------ rtt/TaskContext.cpp | 6 +- rtt/TaskContext.hpp | 25 +++- rtt/marsh/MarshallingService.cpp | 16 +- rtt/rtt-fwd.hpp | 1 + rtt/scripting/ScriptingService.cpp | 20 ++-- rtt/transports/corba/ServiceI.cpp | 4 +- rtt/transports/corba/ServiceRequesterI.cpp | 8 +- rtt/transports/corba/TaskContextI.cpp | 2 +- 15 files changed, 511 insertions(+), 297 deletions(-) create mode 100644 rtt/ServiceInterface.cpp create mode 100644 rtt/ServiceInterface.hpp diff --git a/rtt/DataFlowInterface.hpp b/rtt/DataFlowInterface.hpp index 7f03728..018e693 100644 --- a/rtt/DataFlowInterface.hpp +++ b/rtt/DataFlowInterface.hpp @@ -175,6 +175,17 @@ namespace RTT base::PortInterface& addLocalPort(base::PortInterface& port); /** + * Name and add a Port to this task without registering a service for it. + * @see addLocalPort(base::PortInterface& port) + * @return \a port + */ + base::PortInterface& addLocalPort(const std::string& name, base::PortInterface& port) + { + port.setName(name); + return addLocalPort(port); + } + + /** * Add an Event triggering Port to this task without * registering a service for it. * When data arrives on this port your TaskContext will be woken up @@ -190,6 +201,19 @@ namespace RTT base::InputPortInterface::NewDataOnPortEvent::SlotFunction callback = base::InputPortInterface::NewDataOnPortEvent::SlotFunction() ); /** + * Name and add an Event triggering Port to this task without + * registering a service for it. + * @see addLocalEventPort(base::InputPortInterface& port, base::InputPortInterface::NewDataOnPortEvent::SlotFunction callback = base::InputPortInterface::NewDataOnPortEvent::SlotFunction()) + * @return \a port + */ + base::InputPortInterface& addLocalEventPort(const std::string& name, base::InputPortInterface& port, + base::InputPortInterface::NewDataOnPortEvent::SlotFunction callback = base::InputPortInterface::NewDataOnPortEvent::SlotFunction() ) + { + port.setName(name); + return addLocalEventPort(port, callback); + } + + /** * Get a port of a specific type. */ template< class Type> @@ -225,7 +249,7 @@ namespace RTT /** * The parent Service. May be null in exceptional cases. */ - Service* mservice; + ServiceInterface* mservice; /** * These handles contain the links from an event port's signal to * the TaskContext::dataOnPort method. diff --git a/rtt/Service.cpp b/rtt/Service.cpp index 0d8048a..597550d 100644 --- a/rtt/Service.cpp +++ b/rtt/Service.cpp @@ -49,15 +49,9 @@ namespace RTT { using namespace std; using namespace boost; - Service::shared_ptr Service::Create(const std::string& name, TaskContext* owner) { - return shared_ptr(new Service(name,owner)); - } - - Service::Service(const std::string& name, TaskContext* owner) - : mname(name), mowner(owner), parent() + Service::Service(const std::string& name, TaskContext* owner, shared_ptr parent) + : ServiceInterface(name, owner, parent) { - // Inform DataFlowInterface. - mservice = this; } Service::~Service() @@ -65,51 +59,13 @@ namespace RTT { clear(); } - vector Service::getProviderNames() const { - return keys(services); - } - bool Service::addService( Service::shared_ptr obj ) { - if ( services.find( obj->getName() ) != services.end() ) { - log(Error) << "Could not add Service " << obj->getName() <<": name already in use." <getParent() == 0 && mowner ) { - obj->setOwner( mowner ); - obj->setParent( shared_from_this() ); - } - services[obj->getName()] = obj; - return true; - } - - void Service::removeService( string const& name) { - // carefully written to avoid destructor to call back on us when called from removeService. - if ( services.count(name) ) { - shared_ptr sp = services.find(name)->second; - services.erase(name); - sp.reset(); // this possibly deletes. - } - } - - Service::shared_ptr Service::provides(const std::string& service_name) { - if (service_name == "this") - return shared_from_this(); - shared_ptr sp = services[service_name]; - if (sp) - return sp; - sp = boost::make_shared(service_name, mowner); - sp->setParent( shared_from_this() ); - services[service_name] = sp; - return sp; - } + void Service::setOwner(TaskContext* new_owner) + { + for( SimpleOperations::iterator it= simpleoperations.begin(); it != simpleoperations.end(); ++it) + it->second->setOwner( new_owner ? new_owner->engine() : 0); - Service::shared_ptr Service::getService(const std::string& service_name) { - Services::iterator it = services.find(service_name); - if (it != services.end() ) - return it->second; - return shared_ptr(); + ServiceInterface::setOwner(new_owner); } OperationInterfacePart* Service::getOperation( std::string name ) @@ -130,13 +86,7 @@ namespace RTT { return true; } - bool Service::hasService(const std::string& service_name) { - if (service_name == "this") - return true; - return services.find(service_name) != services.end(); - } - - bool Service::addLocalOperation( OperationBase& op ) + bool Service::addLocalOperation( OperationBase& op ) { Logger::In in("Service::addLocalOperation"); if ( op.getName().empty() ) { @@ -148,12 +98,13 @@ namespace RTT { this->removeOperation(op.getName()); } simpleoperations[op.getName()] = &op; - if (mowner) - op.setOwner(mowner->engine()); + if (getOwner()) + op.setOwner(getOwner()->engine()); return true; } - boost::shared_ptr Service::getLocalOperation( std::string name ) { + boost::shared_ptr Service::getLocalOperation( std::string name ) + { if ( hasOperation(name) ) { return simpleoperations.find(name)->second->getImplementation(); } @@ -172,9 +123,7 @@ namespace RTT { OperationInterface::clear(); ConfigurationInterface::clear(); - while ( !services.empty() ) { - this->removeService( services.begin()->first ); - } + ServiceInterface::clear(); } std::vector Service::getOperationNames() const @@ -201,24 +150,9 @@ namespace RTT { simpleoperations.erase( name ); OperationInterface::remove(name); } - void Service::setOwner(TaskContext* new_owner) { - for( SimpleOperations::iterator it= simpleoperations.begin(); it != simpleoperations.end(); ++it) - it->second->setOwner( new_owner ? new_owner->engine() : 0); - - this->mowner = new_owner; - - for( Services::iterator it= services.begin(); it != services.end(); ++it) { - it->second->setOwner( new_owner ); - if (new_owner) - it->second->setParent( shared_from_this() ); - } - } - void Service::setParent( Service::shared_ptr p) { - parent = p; - } - - internal::OperationCallerC Service::create(std::string name, ExecutionEngine* caller) { + internal::OperationCallerC Service::create(std::string name, ExecutionEngine* caller) + { return internal::OperationCallerC( getPart(name), name, caller ); } diff --git a/rtt/Service.hpp b/rtt/Service.hpp index 1a53e85..c2b9375 100644 --- a/rtt/Service.hpp +++ b/rtt/Service.hpp @@ -40,19 +40,20 @@ #define ORO_SERVICE_PROVIDER_HPP #include "rtt-config.h" -#include "OperationInterface.hpp" -#include "DataFlowInterface.hpp" +#include "rtt-fwd.hpp" + +#include "ServiceInterface.hpp" + +#include "Operation.hpp" #include "internal/OperationInterfacePartFused.hpp" #include "internal/LocalOperationCaller.hpp" #include "internal/OperationCallerC.hpp" #include "internal/UnMember.hpp" #include "internal/GetSignature.hpp" - -#include "ConfigurationInterface.hpp" -#include "Operation.hpp" #ifdef ORO_REMOTING #include "internal/RemoteOperationCaller.hpp" #endif + #include #include #include @@ -70,24 +71,16 @@ namespace RTT * @ingroup Services */ class RTT_API Service - : public OperationInterface, - public ConfigurationInterface, - public DataFlowInterface, - public boost::enable_shared_from_this + : public ServiceInterface { public: - typedef OperationInterface Factory; + typedef boost::shared_ptr shared_ptr; - typedef std::vector ProviderNames; - /** - * Creates a Service with a name and an owner. Each - * service must be owned by a TaskContext and the owner can be - * set afterwards with setOwner. - * @param name The name of this service. - * @param owner The TaskContext that will execute the operations of this service. - */ - static Service::shared_ptr Create(const std::string& name, TaskContext* owner = 0); + static shared_ptr Create(const std::string& name, TaskContext* owner = 0, shared_ptr parent = shared_ptr()) + { + return shared_ptr(new Service(name, owner, parent)); + } /** * Creates a Service with a name and an owner. Each @@ -96,29 +89,19 @@ namespace RTT * @param name The name of this service. * @param owner The TaskContext that will execute the operations of this service. */ - Service(const std::string& name, TaskContext* owner = 0); - - virtual ~Service(); - - /** - * Returns the name of this service instance. - */ - const std::string& getName() const { return mname; } + Service(const std::string& name, TaskContext* owner = 0, shared_ptr parent = shared_ptr()); - /** - * Returns a descriptive text for this service. - */ - const std::string& doc() const { return mdescription; } + virtual ~Service(void); - /** - * Sets the descriptive text for this service. - */ - void doc(const std::string& description) { mdescription = description; } + shared_ptr provides(void) + { + return boost::dynamic_pointer_cast(shared_from_this()); + } - /** - * Changes the name of this service. - */ - void setName(const std::string& name) { mname = name;} + shared_ptr provides(const std::string& service_name) + { + return boost::dynamic_pointer_cast(addService(service_name)); + } /** * Sets the owning TaskContext that will execute the @@ -127,69 +110,6 @@ namespace RTT void setOwner(TaskContext* new_owner); /** - * Sets the parent service in case this service is - * a sub-service. - */ - void setParent(shared_ptr new_parent); - - /** - * The parent is the direct parent of this service. - */ - shared_ptr getParent() const { return parent; } - - /** - * Return a standard container which contains all the sub-service names - * of this Service - */ - virtual ProviderNames getProviderNames() const; - - /** - * The owner is the top-level TaskContext owning this service - * (indirectly). - */ - TaskContext* getOwner() const { return mowner; } - - /** - * Add a new Service to this TaskContext. - * - * @param obj This object becomes owned by this TaskContext. - * - * @return true if it could be added, false if such - * service already exists. - */ - virtual bool addService( shared_ptr obj ); - - /** - * Remove a previously added sub-service. - * @param the name of the service to remove. - */ - virtual void removeService( std::string const& service_name ); - - /** - * Returns this Service. - * @return a shared pointer from this. - */ - Service::shared_ptr provides() { return shared_from_this(); } - - /** - * Returns a sub-Service which resorts under - * this Service. - * @param service_name The name of the sub-service. - */ - Service::shared_ptr provides(const std::string& service_name); - /** - * Returns a shared pointer to strictly a sub-service. - * This method will not return the this pointer when - * service_name equals "this". - */ - shared_ptr getService(const std::string& service_name); - - /** - * Check if this service has the sub-service \a service_name. - */ - bool hasService(const std::string& service_name); - - /** * Clear all added operations from the repository, saving memory space. */ void clear(); @@ -388,21 +308,22 @@ namespace RTT * Reset the implementation of a operation. */ bool resetOperation(std::string name, base::OperationBase* impl); + protected: - typedef std::map< std::string, shared_ptr > Services; - /// the services we implement. - Services services; bool testOperation(base::OperationBase& op); + typedef std::map SimpleOperations; + typedef std::vector OperationList; + SimpleOperations simpleoperations; + OperationList ownedoperations; - std::string mname; - std::string mdescription; - TaskContext* mowner; - shared_ptr parent; }; + + + } diff --git a/rtt/ServiceInterface.cpp b/rtt/ServiceInterface.cpp new file mode 100644 index 0000000..57b45b5 --- /dev/null +++ b/rtt/ServiceInterface.cpp @@ -0,0 +1,143 @@ +/*************************************************************************** + tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 ServiceInterface.cpp + + ServiceInterface.cpp - description + ------------------- + begin : Tue September 07 2010 + copyright : (C) 2010 The SourceWorks + email : peter@thesourceworks.com + + *************************************************************************** + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public * + * License as published by the Free Software Foundation; * + * version 2 of the License. * + * * + * As a special exception, you may use this file as part of a free * + * software library without restriction. Specifically, if other files * + * instantiate templates or use macros or inline functions from this * + * file, or you compile this file and link it with other files to * + * produce an executable, this file does not by itself cause the * + * resulting executable to be covered by the GNU General Public * + * License. This exception does not however invalidate any other * + * reasons why the executable file might be covered by the GNU General * + * Public License. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307 USA * + * * + ***************************************************************************/ + + +#include "ServiceInterface.hpp" +#include "TaskContext.hpp" +#include +#include "internal/mystd.hpp" +#include +#include +#include + +namespace RTT { + using namespace detail; + using namespace std; + using namespace boost; + + ServiceInterface::ServiceInterface(const std::string& name, TaskContext* owner, shared_ptr parent) : + m_name(name), + m_owner(owner), + m_parent(parent) + { + // Inform DataFlowInterface. + mservice = this; + } + + void ServiceInterface::setOwner(TaskContext* new_owner) + { + this->m_owner = new_owner; + + for( SubServices::iterator it= m_sub_services.begin(); it != m_sub_services.end(); ++it) { + it->second->setOwner( new_owner ); + if (new_owner) + it->second->setParent( shared_from_this() ); + } + } + + std::vector ServiceInterface::getServicesNames() const + { + return keys(m_sub_services); + } + + bool ServiceInterface::hasService(const std::string& service_name) + { + if (service_name == "this") + return true; + SubServices::iterator it = m_sub_services.find(service_name); + if (it != m_sub_services.end() ) + return true; + return false; + } + + ServiceInterface::shared_ptr ServiceInterface::getService(const std::string& service_name) + { + if (service_name == "this") + return shared_from_this(); + SubServices::iterator it = m_sub_services.find(service_name); + if (it != m_sub_services.end() ) + return it->second; + return shared_ptr(); + } + + ServiceInterface::shared_ptr ServiceInterface::addService(const std::string& service_name) + { + if (service_name == "this") + return shared_from_this(); + SubServices::iterator it = m_sub_services.find(service_name); + if (it != m_sub_services.end() ) + return it->second; + m_sub_services[service_name] = Create(service_name); + return m_sub_services[service_name]; + } + + void ServiceInterface::removeService(const std::string& service_name) + { + // carefully written to avoid destructor to call back on us when called from removeServiceInterface. + SubServices::iterator it = m_sub_services.find(service_name); + if (it != m_sub_services.end() ) { + shared_ptr sp = it->second; + m_sub_services.erase(it); + sp.reset(); // this possibly deletes. + } + } + + bool ServiceInterface::addService( ServiceInterface::shared_ptr obj ) + { + SubServices::iterator it = m_sub_services.find(obj->getName()); + if (it != m_sub_services.end() ) { + log(Error) << "Could not add ServiceInterface " << obj->getName() <<": name already in use." <getParent() == 0) && m_owner ) { + obj->setOwner( m_owner ); + obj->setParent( shared_from_this() ); + } + m_sub_services[obj->getName()] = obj; + return true; + } + + void ServiceInterface::clear(void) + { + while ( !m_sub_services.empty() ) { + this->removeService( m_sub_services.begin()->first ); + } + } + +} diff --git a/rtt/ServiceInterface.hpp b/rtt/ServiceInterface.hpp new file mode 100644 index 0000000..6f40231 --- /dev/null +++ b/rtt/ServiceInterface.hpp @@ -0,0 +1,210 @@ +/*************************************************************************** + tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 ServiceInterface.hpp + + ServiceInterface.hpp - description + ------------------- + begin : Tue September 07 2010 + copyright : (C) 2010 The SourceWorks + email : peter@thesourceworks.com + + *************************************************************************** + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public * + * License as published by the Free Software Foundation; * + * version 2 of the License. * + * * + * As a special exception, you may use this file as part of a free * + * software library without restriction. Specifically, if other files * + * instantiate templates or use macros or inline functions from this * + * file, or you compile this file and link it with other files to * + * produce an executable, this file does not by itself cause the * + * resulting executable to be covered by the GNU General Public * + * License. This exception does not however invalidate any other * + * reasons why the executable file might be covered by the GNU General * + * Public License. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307 USA * + * * + ***************************************************************************/ + + +#ifndef ORO_SERVICE_INTERFACE_HPP +#define ORO_SERVICE_INTERFACE_HPP + +#include "rtt-config.h" + +#include "OperationInterface.hpp" +#include "DataFlowInterface.hpp" +#include "ConfigurationInterface.hpp" + +#include +#include + +#include +#include + +namespace RTT +{ + /** + * This class allows storage and retrieval of operations, + * attributes and properties provided by a component. + * + * Services can be nested in sub-services, although this is rare. + * + * @ingroup Services + */ + class RTT_API ServiceInterface + : public OperationInterface, + public ConfigurationInterface, + public DataFlowInterface, + public boost::enable_shared_from_this + { + public: + + typedef boost::shared_ptr shared_ptr; + + /** + * Creates a Service with a name and an owner. Each + * service must be owned by a TaskContext and the owner can be + * set afterwards with setOwner. + * @param name The name of this service. + * @param owner The TaskContext that will execute the operations of this service. + */ + static shared_ptr Create(const std::string& name, TaskContext* owner = 0, shared_ptr parent = shared_ptr()) + { + return shared_ptr(new ServiceInterface(name, owner, parent)); + } + + /** + * Creates a Service with a name and an owner. Each + * service must be owned by a TaskContext and the owner can be + * set afterwards with setOwner. + * @param name The name of this service. + * @param owner The TaskContext that will execute the operations of this service. + */ + ServiceInterface(const std::string& name, TaskContext* owner = 0, shared_ptr parent = shared_ptr()); + + virtual ~ServiceInterface(void) {} + + /** + * Returns the name of this service instance. + */ + const std::string& getName() const { return m_name; } + + /** + * Changes the name of this service. + */ + void setName(const std::string& new_name) { m_name = new_name;} + + /** + * Returns a descriptive text for this service. + */ + const std::string& doc() const { return m_description; } + + /** + * Sets the descriptive text for this service. + */ + void doc(const std::string& new_description) { m_description = new_description; } + + /** + * The owner is the top-level TaskContext owning this service + * (indirectly). + */ + TaskContext* getOwner() const { return m_owner; } + + /** + * Sets the owning TaskContext that will execute the + * operations in this service. + */ + void setOwner(TaskContext* new_owner); + + /** + * The parent is the direct parent of this service. + */ + shared_ptr getParent() const { return m_parent; } + + /** + * Sets the parent service in case this service is + * a sub-service. + */ + void setParent(shared_ptr new_parent) { m_parent = new_parent; } + + + /** + * Return a standard container which contains all the sub-service names + * of this Service + */ + std::vector getServicesNames() const; + + /** + * Check if this service has the sub-service \a service_name. + * This method will return the this pointer when + * service_name equals "this". + */ + bool hasService(const std::string& service_name); + + /** + * Returns a shared pointer to a sub-service or + * null if the service doesn't exist. + * This method will return the this pointer when + * service_name equals "this". + */ + shared_ptr getService(const std::string& service_name); + + /** + * Returns a shared pointer to a sub-service. + * This method will return the this pointer when + * service_name equals "this". + */ + shared_ptr addService(const std::string& service_name); + + /** + * Remove a previously added sub-service. + * @param the name of the service to remove. + */ + void removeService(const std::string& service_name ); + + /** + * Add a new Service to this TaskContext. + * + * @param obj This object becomes owned by this TaskContext. + * + * @return true if it could be added, false if such + * service already exists. + */ + bool addService( shared_ptr obj ); + + /** + * Remove all sub-service. + */ + void clear(void); + + + private: + + std::string m_description; + + std::string m_name; + + TaskContext* m_owner; + + shared_ptr m_parent; + + // the services we implement. + typedef std::map< std::string, shared_ptr > SubServices; + + SubServices m_sub_services; + + }; +} + + +#endif diff --git a/rtt/ServiceRequester.cpp b/rtt/ServiceRequester.cpp index 4e8bdf2..a82d053 100644 --- a/rtt/ServiceRequester.cpp +++ b/rtt/ServiceRequester.cpp @@ -37,7 +37,6 @@ #include "ServiceRequester.hpp" -#include "Service.hpp" #include "internal/mystd.hpp" #include "Logger.hpp" #include "TaskContext.hpp" @@ -51,12 +50,8 @@ namespace RTT using namespace detail; using namespace std; - ServiceRequester::ServiceRequester(const std::string& name, TaskContext* tc) : - mrname(name), mrowner(tc) - { - } - - ServiceRequester::~ServiceRequester() + ServiceRequester::ServiceRequester(const std::string& name, TaskContext* owner, ServiceInterface::shared_ptr parent) + : ServiceInterface(name, owner, parent) { } @@ -76,11 +71,6 @@ namespace RTT return keys(mmethods); } - std::vector ServiceRequester::getRequesterNames() const - { - return keys(mrequests); - } - OperationCallerBaseInvoker& ServiceRequester::getOperationCaller(const std::string& name) { return *mmethods.find(name)->second; @@ -90,18 +80,18 @@ namespace RTT for (OperationCallers::iterator it = mmethods.begin(); it != mmethods.end(); ++it) { if ( !it->second->ready() ) { if (sp->hasOperation( it->first )) { - it->second->setImplementation( sp->getLocalOperation( it->first ), mrowner ? mrowner->engine() : 0 ); + it->second->setImplementation( sp->getLocalOperation( it->first ), getOwner() ? getOwner()->engine() : 0 ); if ( it->second->ready() ) { - if (mrowner) + if (getOwner()) log(Debug) << "Successfully set up OperationCaller " << it->first <first << " has no caller set."<hasMember( it->first )) { - it->second->setImplementationPart( sp->getOperation( it->first ), mrowner ? mrowner->engine() : 0 ); + it->second->setImplementationPart( sp->getOperation( it->first ), getOwner() ? getOwner()->engine() : 0 ); if ( it->second->ready() ) { - if (mrowner) + if (getOwner()) log(Debug) << "Successfully set up OperationCaller " << it->first <first << " has no caller set."<(), ee ) - ); - } - bool ServiceRequester::ready() const { for (OperationCallers::const_iterator it = mmethods.begin(); it != mmethods.end(); ++it) if ( !it->second->ready() ) { - log(Debug) << "ServiceRequeste: "<< it->first << " not set up." <first << " not set up." <(), ee ) + ); + mprovider = shared_ptr(); + } + } diff --git a/rtt/ServiceRequester.hpp b/rtt/ServiceRequester.hpp index ac8ea53..5ddc2a4 100644 --- a/rtt/ServiceRequester.hpp +++ b/rtt/ServiceRequester.hpp @@ -41,8 +41,10 @@ #include "rtt-config.h" #include "rtt-fwd.hpp" -#include "base/OperationCallerBaseInvoker.hpp" + #include "Service.hpp" +#include "ServiceInterface.hpp" +#include "base/OperationCallerBaseInvoker.hpp" #include #include #include @@ -61,56 +63,37 @@ namespace RTT * to it using addOperationCaller. @see RTT::Scripting for an example. */ class RTT_API ServiceRequester + : public ServiceInterface { public: - typedef std::vector RequesterNames; - typedef std::vector OperationCallerNames; - ServiceRequester(const std::string& name, TaskContext* owner = 0); - virtual ~ServiceRequester(); - const std::string& getRequestName() const { return mrname; } + typedef boost::shared_ptr shared_ptr; - RequesterNames getRequesterNames() const; + static shared_ptr Create(const std::string& name, TaskContext* owner = 0, shared_ptr parent = shared_ptr()) + { + return shared_ptr(new ServiceRequester(name, owner, parent)); + } - /** - * The owner is the top-level TaskContext owning this service - * (indirectly). - */ - TaskContext* getServiceOwner() const { return mrowner; } + ServiceRequester(const std::string& name, TaskContext* owner = 0, ServiceInterface::shared_ptr parent = shared_ptr()); - /** - * Returns the service we're referencing. - * In case you used connectTo to more than one service, - * this returns the service which was used when connectTo - * first returned true. - */ - Service::shared_ptr getReferencedService(); + virtual ~ServiceRequester(void) {} - bool addOperationCaller( base::OperationCallerBaseInvoker& mbi); + shared_ptr requires(void) + { + return boost::dynamic_pointer_cast(shared_from_this()); + } - OperationCallerNames getOperationCallerNames() const; + shared_ptr requires(const std::string& service_name) + { + return boost::dynamic_pointer_cast(addService(service_name)); + } - base::OperationCallerBaseInvoker& getOperationCaller(const std::string& name); - ServiceRequester* requires() { return this; } + bool addOperationCaller( base::OperationCallerBaseInvoker& mbi); - ServiceRequester* requires(const std::string& service_name) { - ServiceRequester* sp = mrequests[service_name]; - if (sp) - return sp; - sp = new ServiceRequester(service_name, mrowner); - mrequests[service_name] = sp; - return sp; - } + std::vector getOperationCallerNames() const; - /** - * Query if this service requires certain sub-services. - * @param service_name - * @return - */ - bool requiresService(const std::string& service_name) { - return mrequests.find(service_name) != mrequests.end(); - } + base::OperationCallerBaseInvoker& getOperationCaller(const std::string& name); /** * Connects this service's methods to the operations provided by op. @@ -137,17 +120,12 @@ namespace RTT void disconnect(); protected: - typedef std::map< std::string, ServiceRequester* > Requests; - /// the services we implement. - Requests mrequests; /// Our methods typedef std::map OperationCallers; OperationCallers mmethods; - std::string mrname; - TaskContext* mrowner; - Service::shared_ptr mprovider; + ServiceInterface::shared_ptr mprovider; }; } diff --git a/rtt/TaskContext.cpp b/rtt/TaskContext.cpp index 5d1b747..66b941b 100644 --- a/rtt/TaskContext.cpp +++ b/rtt/TaskContext.cpp @@ -131,7 +131,7 @@ namespace RTT // [Rule no 2: Don't call virtual functions in a constructor.] tcservice->clear(); - delete tcrequests; + tcrequests->clear(); // remove from all users. while( !musers.empty() ) { @@ -183,8 +183,8 @@ namespace RTT const std::string& location = this->getName(); Logger::In in( location.c_str() ); - vector myreqs = this->requires()->getRequesterNames(); - vector peerreqs = peer->requires()->getRequesterNames(); + vector myreqs = this->requires()->getServicesNames(); + vector peerreqs = peer->requires()->getServicesNames(); this->requires()->connectTo( peer->provides() ); for (vector::iterator it = myreqs.begin(); diff --git a/rtt/TaskContext.hpp b/rtt/TaskContext.hpp index b1f53b2..6763ec7 100644 --- a/rtt/TaskContext.hpp +++ b/rtt/TaskContext.hpp @@ -265,27 +265,37 @@ namespace RTT * Returns this Service. * @return a shared pointer from this. */ - Service::shared_ptr provides() { return tcservice; } + Service::shared_ptr provides() + { + return tcservice; + } /** * Returns a sub-Service which resorts under * this Service. * @param service_name The name of the sub-service. */ - Service::shared_ptr provides(const std::string& service_name) { return tcservice->provides(service_name); } + Service::shared_ptr provides(const std::string& service_name) + { + return tcservice->provides(service_name); + } /** * Returns the object that manages which methods this Task * requires to be implemented by another task. */ - ServiceRequester* requires() { return tcrequests; } + ServiceRequester* requires() + { + return tcrequests.get(); + } /** * Returns the object that manages which methods this Task * requires to be implemented by another service. */ - ServiceRequester* requires(const std::string& service_name) { - return tcrequests->requires(service_name); + ServiceRequester* requires(const std::string& service_name) + { + return tcrequests->requires(service_name).get(); } /** @@ -646,8 +656,9 @@ namespace RTT typedef std::map > LocalServices; LocalServices localservs; - Service::shared_ptr tcservice; - ServiceRequester* tcrequests; + Service::shared_ptr tcservice; // m_service_providers + ServiceRequester::shared_ptr tcrequests; // m_service_requesters + os::Mutex mportlock; // non copyable diff --git a/rtt/marsh/MarshallingService.cpp b/rtt/marsh/MarshallingService.cpp index 87d1435..155ac6f 100644 --- a/rtt/marsh/MarshallingService.cpp +++ b/rtt/marsh/MarshallingService.cpp @@ -90,44 +90,44 @@ namespace RTT { bool MarshallingService::loadProperties(const std::string& filename) const { PropertyLoader pl; - return pl.load( filename, mowner ); + return pl.load( filename, getOwner() ); } bool MarshallingService::storeProperties(const std::string& filename) const { PropertyLoader pl; - return pl.store( filename, mowner ); + return pl.store( filename, getOwner() ); } bool MarshallingService::readProperties(const std::string& filename) const { PropertyLoader pl; - return pl.configure( filename, mowner, true); // all + return pl.configure( filename, getOwner(), true); // all } bool MarshallingService::updateProperties(const std::string& filename) const { PropertyLoader pl; - return pl.configure( filename, mowner, false); // not all + return pl.configure( filename, getOwner(), false); // not all } bool MarshallingService::writeProperties(const std::string& filename) const { PropertyLoader pl; - return pl.save( filename, mowner, true); + return pl.save( filename, getOwner(), true); } bool MarshallingService::updateFile(const std::string& filename) const { PropertyLoader pl; - return pl.save( filename, mowner, false); + return pl.save( filename, getOwner(), false); } bool MarshallingService::readProperty(const std::string& name, const std::string& filename) { PropertyLoader p; - return p.configure(filename, mowner, name); + return p.configure(filename, getOwner(), name); } bool MarshallingService::writeProperty(const std::string& name, const std::string& filename) { PropertyLoader p; - return p.save(filename, mowner, name); + return p.save(filename, getOwner(), name); } diff --git a/rtt/rtt-fwd.hpp b/rtt/rtt-fwd.hpp index 3a44b81..94f4465 100644 --- a/rtt/rtt-fwd.hpp +++ b/rtt/rtt-fwd.hpp @@ -82,6 +82,7 @@ namespace RTT class DataFlowInterface; class OperationInterface; class OperationInterfacePart; + class ServiceInterface; class Service; class ServiceRequester; typedef boost::shared_ptr ServicePtr; diff --git a/rtt/scripting/ScriptingService.cpp b/rtt/scripting/ScriptingService.cpp index 93ec43c..7374de4 100644 --- a/rtt/scripting/ScriptingService.cpp +++ b/rtt/scripting/ScriptingService.cpp @@ -218,7 +218,7 @@ namespace RTT { // first load parent. states[sc->getName()] = sc; - mowner->engine()->runFunction( sc.get() ); + getOwner()->engine()->runFunction( sc.get() ); // then load children. for (it = sc->getChildren().begin(); it != sc->getChildren().end(); ++it) @@ -285,7 +285,7 @@ namespace RTT { // lastly, unload the parent. states.erase(it); - mowner->engine()->removeFunction( sc.get() ); + getOwner()->engine()->removeFunction( sc.get() ); } bool ScriptingService::deleteStateMachine(const string& name) @@ -350,7 +350,7 @@ namespace RTT { } programs[pi->getName()] = pi; pi->reset(); - if ( mowner->engine()->runFunction( pi.get() ) == false) { + if ( getOwner()->engine()->runFunction( pi.get() ) == false) { programs.erase(pi->getName()); log(Error) << "Could not load Program "<< pi->getName() << " in ExecutionEngine."<engine()->removeFunction( it->second.get() ); + getOwner()->engine()->removeFunction( it->second.get() ); programs.erase( it ); return true; } @@ -493,7 +493,7 @@ namespace RTT { int ScriptingService::execute(const string& code ){ if (sproc == 0) - sproc = new StatementProcessor(mowner); + sproc = new StatementProcessor(getOwner()); return sproc->execute( code ); } @@ -522,7 +522,7 @@ namespace RTT { Functions ret; try { Logger::log() << Logger::Info << "Parsing file "<getName() << Logger::endl; - if ( mowner->engine()->runFunction( it->get() ) == false) { + if ( getOwner()->engine()->runFunction( it->get() ) == false) { Logger::log() << Logger::Error << "Could not run Function '"<< (*it)->getName() <<"' :" << Logger::nl; Logger::log() << "Processor not accepting or function queue is full." << Logger::endl; } else @@ -580,7 +580,7 @@ namespace RTT { Logger::In in("ScriptingService"); Parser parser; try { - parser.runScript(code, mowner, this, filename ); + parser.runScript(code, getOwner(), this, filename ); } catch( const file_parse_exception& exc ) { @@ -619,7 +619,7 @@ namespace RTT { } try { Logger::log() << Logger::Info << "Parsing file "<getProviderNames(); + std::vector names = mservice->getServicesNames(); ::RTT::corba::CService::CProviderNames_var result = new ::RTT::corba::CService::CProviderNames(); result->length( names.size() ); for (unsigned int i=0; i != names.size(); ++i ) @@ -116,7 +116,7 @@ char * RTT_corba_CService_i::getServiceDescription ( ::RTT::corba::CService_ptr RTT_corba_CService_i::getService ( const char * service_name) { - Service::shared_ptr provider = mservice->getService(service_name); + Service::shared_ptr provider = boost::dynamic_pointer_cast(mservice->getService(service_name)); if ( !provider ) return RTT::corba::CService::_nil(); diff --git a/rtt/transports/corba/ServiceRequesterI.cpp b/rtt/transports/corba/ServiceRequesterI.cpp index 35ef7d2..361e71b 100644 --- a/rtt/transports/corba/ServiceRequesterI.cpp +++ b/rtt/transports/corba/ServiceRequesterI.cpp @@ -85,13 +85,13 @@ RTT_corba_CServiceRequester_i::~RTT_corba_CServiceRequester_i (void) char * RTT_corba_CServiceRequester_i::getRequestName ( void) { - return CORBA::string_dup( mservice->getRequestName().c_str() ); + return CORBA::string_dup( mservice->getName().c_str() ); } ::RTT::corba::CRequestNames * RTT_corba_CServiceRequester_i::getRequestNames ( void) { - ServiceRequester::RequesterNames names = mservice->getRequesterNames(); + std::vector names = mservice->getServicesNames(); ::RTT::corba::CRequestNames_var result = new ::RTT::corba::CRequestNames(); result->length( names.size() ); for (unsigned int i=0; i != names.size(); ++i ) @@ -103,7 +103,7 @@ char * RTT_corba_CServiceRequester_i::getRequestName ( ::RTT::corba::COperationCallerNames * RTT_corba_CServiceRequester_i::getOperationCallerNames ( void) { - ServiceRequester::OperationCallerNames names = mservice->getOperationCallerNames(); + std::vector names = mservice->getOperationCallerNames(); ::RTT::corba::COperationCallerNames_var result = new ::RTT::corba::COperationCallerNames(); result->length( names.size() ); for (unsigned int i=0; i != names.size(); ++i ) @@ -121,7 +121,7 @@ char * RTT_corba_CServiceRequester_i::getRequestName ( ::CORBA::Boolean RTT_corba_CServiceRequester_i::hasRequest ( const char * name) { - return mservice->requiresService( name ); + return mservice->hasService( name ); } ::CORBA::Boolean RTT_corba_CServiceRequester_i::connectTo ( diff --git a/rtt/transports/corba/TaskContextI.cpp b/rtt/transports/corba/TaskContextI.cpp index b9d832b..afbbfb6 100644 --- a/rtt/transports/corba/TaskContextI.cpp +++ b/rtt/transports/corba/TaskContextI.cpp @@ -221,7 +221,7 @@ char * RTT_corba_CTaskContext_i::getDescription ( ::RTT::corba::CServiceRequester_ptr RTT_corba_CTaskContext_i::getRequester ( const char * service_name) { - if ( mtask->requires()->requiresService(service_name) == false) + if ( mtask->requires()->hasService(service_name) == false) return CServiceRequester::_nil(); // Creates service requester for "this" if ( CORBA::is_nil( mRequest ) ) { -- 1.7.0.4