Orocos Real-Time Toolkit  2.6.0
TaskContext.hpp
00001 /***************************************************************************
00002   tag: Peter Soetens  Tue Dec 21 22:43:08 CET 2004  TaskContext.hpp
00003 
00004                         TaskContext.hpp -  description
00005                            -------------------
00006     begin                : Tue December 21 2004
00007     copyright            : (C) 2004 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.ac.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 #ifndef ORO_TASK_CONTEXT_HPP
00040 #define ORO_TASK_CONTEXT_HPP
00041 
00042 
00043 #include "rtt-config.h"
00044 #include "Service.hpp"
00045 #include "ServiceRequester.hpp"
00046 #include "DataFlowInterface.hpp"
00047 #include "ExecutionEngine.hpp"
00048 #include "base/TaskCore.hpp"
00049 #include <boost/make_shared.hpp>
00050 
00051 #include <string>
00052 #include <map>
00053 
00054 namespace RTT
00055 {
00093     class RTT_API TaskContext
00094         : public base::TaskCore
00095     {
00096     public:
00100         typedef std::vector< std::string > PeerList;
00101 
00110         TaskContext( const std::string& name, TaskState initial_state = Stopped );
00111 
00121         TaskContext(const std::string& name, ExecutionEngine* parent, TaskState initial_state = Stopped );
00122 
00123         virtual ~TaskContext();
00124 
00128         virtual const std::string& getName() { return tcservice->getName(); }
00129 
00144         bool setActivity( base::ActivityInterface* new_act );
00145 
00151         base::ActivityInterface* getActivity();
00152 
00172         template<typename T>
00173         T* getActivity() { return dynamic_cast<T*>(getActivity()); }
00174 
00180         virtual void clear();
00181 
00190         virtual bool ready();
00191 
00192         virtual bool start();
00193         virtual bool stop();
00194 
00209         virtual bool addPeer( TaskContext* peer, std::string alias = "" );
00210 
00214         virtual void removePeer( const std::string& name );
00215 
00219         virtual void removePeer( TaskContext* peer );
00220 
00224         virtual bool connectPeers( TaskContext* peer );
00225 
00231         virtual void disconnect();
00232 
00236         virtual void disconnectPeers( const std::string& name );
00237 
00242         virtual PeerList getPeerList() const;
00243 
00247         virtual bool hasPeer( const std::string& peer_name ) const;
00248 
00253         virtual TaskContext* getPeer(const std::string& peer_name ) const;
00268         Service::shared_ptr provides() { return tcservice; }
00269 
00275         Service::shared_ptr provides(const std::string& service_name) { return tcservice->provides(service_name); }
00276 
00281         ServiceRequester* requires() { return tcrequests; }
00282 
00287         ServiceRequester* requires(const std::string& service_name) {
00288             return tcrequests->requires(service_name);
00289         }
00290 
00294         virtual bool connectServices( TaskContext* peer);
00295 
00308         template<class ServiceType>
00309         boost::shared_ptr<ServiceType> getProvider(const std::string& name) {
00310             if (!prepareProvide(name)) return boost::shared_ptr<ServiceType>();
00311             LocalServices::iterator it = localservs.find(name);
00312             if (  it != localservs.end() ) {
00313                 return boost::dynamic_pointer_cast<ServiceType>(it->second);
00314             }
00315             boost::shared_ptr<ServiceType> st = boost::make_shared<ServiceType>(this);
00316             st->connectTo( provides(name) );
00317             localservs[name] = st;
00318             return st;
00319         }
00320 
00326         bool loadService(const std::string& service_name);
00327 
00346         template<class Signature>
00347         Operation<Signature>& addOperation( Operation<Signature>& op )
00348         {
00349             return tcservice->addOperation(op);
00350         }
00351 
00356         template<class Func, class Service>
00357         Operation< typename internal::GetSignature<Func>::Signature >&
00358         addOperation( const std::string name, Func func, Service* serv, ExecutionThread et = ClientThread )
00359         {
00360             return tcservice->addOperation(name,func, serv, et);
00361         }
00362 
00367         template<class Signature>
00368         Operation< Signature >&
00369         addOperation( const std::string name, Signature* func, ExecutionThread et = ClientThread )
00370         {
00371             return tcservice->addOperation(name, func, et);
00372         }
00373 
00383         OperationInterfacePart* getOperation( std::string name )
00384         {
00385             return tcservice->getOperation(name);
00386         }
00387 
00391         OperationInterface* operations() { return this->provides().get(); }
00392 
00410         template<class T>
00411         bool addAttribute( const std::string& name, T& attr) {
00412             return tcservice->addAttribute(name, attr);
00413         }
00414 
00423         template<class T>
00424         bool addConstant( const std::string& name, const T& attr) {
00425             return tcservice->addConstant(name, attr);
00426         }
00427 
00437         bool addAttribute( base::AttributeBase& a )
00438         {
00439             return tcservice->addAttribute(a);
00440         }
00441 
00450         base::AttributeBase* getAttribute( const std::string& name ) const
00451         {
00452             return tcservice->getAttribute(name);
00453         }
00454 
00458         ConfigurationInterface* attributes() { return this->provides().get(); }
00459 
00478         template<class T>
00479         Property<T>& addProperty( const std::string& name, T& attr) {
00480             return tcservice->addProperty(name, attr);
00481         }
00482 
00487         bool addProperty( base::PropertyBase& pb ) {
00488             return tcservice->addProperty(pb);
00489         }
00490 
00498         base::PropertyBase* getProperty(const std::string& name) const
00499         {
00500             return tcservice->getProperty(name);
00501         }
00502 
00506         PropertyBag* properties() { return this->provides()->properties(); }
00507 
00523         base::PortInterface& addPort(const std::string& name, base::PortInterface& port) {
00524             port.setName(name);
00525             return ports()->addPort(port);
00526         }
00527 
00533         base::PortInterface& addPort(base::PortInterface& port) {
00534             return ports()->addPort(port);
00535         }
00536 
00537         typedef boost::function<void(base::PortInterface*)> SlotFunction;
00547         base::InputPortInterface& addEventPort(const std::string& name, base::InputPortInterface& port, SlotFunction callback = SlotFunction() ) {
00548             port.setName(name);
00549             return ports()->addEventPort(port,callback);
00550         }
00551 
00560         base::InputPortInterface& addEventPort(base::InputPortInterface& port, SlotFunction callback = SlotFunction() ) {
00561             return ports()->addEventPort(port,callback);
00562         }
00563 
00569         base::PortInterface* getPort(const std::string& name) const {
00570             return ports()->getPort(name);
00571         }
00572 
00573 
00577         DataFlowInterface* ports() {
00578             return tcservice.get();
00579         }
00580 
00584         const DataFlowInterface* ports() const {
00585             return tcservice.get();
00586         }
00587 
00591         virtual bool connectPorts( TaskContext* peer );
00594     protected:
00602         void forceActivity( base::ActivityInterface* new_act);
00603     private:
00604 
00605         typedef std::map< std::string, TaskContext* > PeerMap;
00606         typedef std::vector< TaskContext* > Users;
00608         PeerMap         _task_map;
00610         Users         musers;
00611 
00616         void addUser(TaskContext* user);
00617 
00622         void removeUser(TaskContext* user);
00623 
00627         void setup();
00628 
00629         friend class DataFlowInterface;
00630         internal::MWSRQueue<base::PortInterface*>* portqueue;
00631         typedef std::map<base::PortInterface*, SlotFunction > UserCallbacks;
00632         UserCallbacks user_callbacks;
00633 
00638         void dataOnPort(base::PortInterface* port);
00644         bool dataOnPortSize(unsigned int max);
00648         void dataOnPortCallback(base::InputPortInterface* port, SlotFunction callback);
00652         void dataOnPortRemoved(base::PortInterface* port);
00653 
00658         void prepareUpdateHook();
00659 
00667         bool prepareProvide(const std::string& name);
00668 
00669         typedef std::map<std::string, boost::shared_ptr<ServiceRequester> > LocalServices;
00670         LocalServices localservs;
00671 
00672         Service::shared_ptr tcservice;
00673         ServiceRequester*           tcrequests;
00674         os::Mutex mportlock;
00675 
00676         // non copyable
00677         TaskContext( TaskContext& );
00678 
00683         base::ActivityInterface::shared_ptr our_act;
00684     };
00685 
00691     RTT_API bool connectPorts(TaskContext* A, TaskContext* B);
00692 
00699     RTT_API bool connectPeers(TaskContext* A, TaskContext* B);
00700 }
00701 
00702 #endif