Orocos Real-Time Toolkit  2.5.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 
00339         template<class Signature>
00340         Operation<Signature>& addOperation( Operation<Signature>& op )
00341         {
00342             return tcservice->addOperation(op);
00343         }
00344 
00349         template<class Func, class Service>
00350         Operation< typename internal::GetSignature<Func>::Signature >&
00351         addOperation( const std::string name, Func func, Service* serv, ExecutionThread et = ClientThread )
00352         {
00353             return tcservice->addOperation(name,func, serv, et);
00354         }
00355 
00360         template<class Signature>
00361         Operation< Signature >&
00362         addOperation( const std::string name, Signature* func, ExecutionThread et = ClientThread )
00363         {
00364             return tcservice->addOperation(name, func, et);
00365         }
00366 
00376         OperationInterfacePart* getOperation( std::string name )
00377         {
00378             return tcservice->getOperation(name);
00379         }
00380 
00384         OperationInterface* operations() { return this->provides().get(); }
00385 
00403         template<class T>
00404         bool addAttribute( const std::string& name, T& attr) {
00405             return tcservice->addAttribute(name, attr);
00406         }
00407 
00416         template<class T>
00417         bool addConstant( const std::string& name, const T& attr) {
00418             return tcservice->addConstant(name, attr);
00419         }
00420 
00430         bool addAttribute( base::AttributeBase& a )
00431         {
00432             return tcservice->addAttribute(a);
00433         }
00434 
00443         base::AttributeBase* getAttribute( const std::string& name ) const
00444         {
00445             return tcservice->getAttribute(name);
00446         }
00447 
00451         ConfigurationInterface* attributes() { return this->provides().get(); }
00452 
00471         template<class T>
00472         Property<T>& addProperty( const std::string& name, T& attr) {
00473             return tcservice->addProperty(name, attr);
00474         }
00475 
00480         bool addProperty( base::PropertyBase& pb ) {
00481             return tcservice->addProperty(pb);
00482         }
00483 
00491         base::PropertyBase* getProperty(const std::string& name) const
00492         {
00493             return tcservice->getProperty(name);
00494         }
00495 
00499         PropertyBag* properties() { return this->provides()->properties(); }
00500 
00516         base::PortInterface& addPort(const std::string& name, base::PortInterface& port) {
00517             port.setName(name);
00518             return ports()->addPort(port);
00519         }
00520 
00526         base::PortInterface& addPort(base::PortInterface& port) {
00527             return ports()->addPort(port);
00528         }
00529 
00530         typedef boost::function<void(base::PortInterface*)> SlotFunction;
00540         base::InputPortInterface& addEventPort(const std::string& name, base::InputPortInterface& port, SlotFunction callback = SlotFunction() ) {
00541             port.setName(name);
00542             return ports()->addEventPort(port,callback);
00543         }
00544 
00553         base::InputPortInterface& addEventPort(base::InputPortInterface& port, SlotFunction callback = SlotFunction() ) {
00554             return ports()->addEventPort(port,callback);
00555         }
00556 
00562         base::PortInterface* getPort(const std::string& name) const {
00563             return ports()->getPort(name);
00564         }
00565 
00566 
00570         DataFlowInterface* ports() {
00571             return tcservice.get();
00572         }
00573 
00577         const DataFlowInterface* ports() const {
00578             return tcservice.get();
00579         }
00580 
00584         virtual bool connectPorts( TaskContext* peer );
00587     protected:
00595         void forceActivity( base::ActivityInterface* new_act);
00596     private:
00597 
00598         typedef std::map< std::string, TaskContext* > PeerMap;
00599         typedef std::vector< TaskContext* > Users;
00601         PeerMap         _task_map;
00603         Users         musers;
00604 
00609         void addUser(TaskContext* user);
00610 
00615         void removeUser(TaskContext* user);
00616 
00620         void setup();
00621 
00622         friend class DataFlowInterface;
00623         internal::MWSRQueue<base::PortInterface*>* portqueue;
00624         typedef std::map<base::PortInterface*, SlotFunction > UserCallbacks;
00625         UserCallbacks user_callbacks;
00626 
00631         void dataOnPort(base::PortInterface* port);
00637         bool dataOnPortSize(unsigned int max);
00641         void dataOnPortCallback(base::InputPortInterface* port, SlotFunction callback);
00645         void dataOnPortRemoved(base::PortInterface* port);
00646 
00651         void prepareUpdateHook();
00652 
00660         bool prepareProvide(const std::string& name);
00661 
00662         typedef std::map<std::string, boost::shared_ptr<ServiceRequester> > LocalServices;
00663         LocalServices localservs;
00664 
00665         Service::shared_ptr tcservice;
00666         ServiceRequester*           tcrequests;
00667         os::Mutex mportlock;
00668 
00669         // non copyable
00670         TaskContext( TaskContext& );
00671 
00676         base::ActivityInterface::shared_ptr our_act;
00677     };
00678 
00684     RTT_API bool connectPorts(TaskContext* A, TaskContext* B);
00685 
00692     RTT_API bool connectPeers(TaskContext* A, TaskContext* B);
00693 }
00694 
00695 #endif