CORBAExpression.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Mon Jun 26 13:25:58 CEST 2006  CORBAExpression.hpp
00003 
00004                         CORBAExpression.hpp -  description
00005                            -------------------
00006     begin                : Mon June 26 2006
00007     copyright            : (C) 2006 Peter Soetens
00008     email                : peter.soetens@fmtc.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_CORBAEXPRESSION_HPP
00040 #define ORO_CORBAEXPRESSION_HPP
00041 
00042 #include "../DataSource.hpp"
00043 #include "../Logger.hpp"
00044 #include "../BuildType.hpp"
00045 #include "../CommandInterface.hpp"
00046 #include "../CommandBinary.hpp"
00047 #include "CorbaConversion.hpp"
00048 #include <cassert>
00049 
00050 namespace RTT
00051 {namespace Corba
00052 {
00053     struct  UpdatedCommand : public ::RTT::CommandInterface
00054     {
00055         DataSourceBase::shared_ptr mds;
00056         UpdatedCommand( DataSourceBase* ds )
00057             :mds(ds)
00058         {}
00059 
00060         bool execute() {
00061             mds->updated();
00062             return true;
00063         }
00064 
00065         void readArguments() {}
00066 
00067         ::RTT::CommandInterface* clone() const {
00068             return new UpdatedCommand(mds.get());
00069         }
00070 
00071         ::RTT::CommandInterface* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00072             return new UpdatedCommand(mds->copy(alreadyCloned));
00073         }
00074     };
00075 
00076 
00080     template<class T>
00081     class CORBAExpression
00082         : public DataSource<T>
00083     {
00084         Corba::Expression_var mexpr;
00085         mutable typename DataSource<T>::value_t last_value;
00086     public:
00087         CORBAExpression( Corba::Expression_ptr expr )
00088             : mexpr( Corba::Expression::_duplicate( expr ) ), last_value()
00089         {
00090             assert( !CORBA::is_nil(mexpr) );
00091         }
00092 
00093         void* server(int p, void* arg)
00094         {
00095             if ( p == ORO_CORBA_PROTOCOL_ID)
00096                 return Corba::Expression::_duplicate( mexpr );
00097             return 0;
00098         }
00099 
00100         void* server(int p, void* arg) const
00101         {
00102             if ( p == ORO_CORBA_PROTOCOL_ID)
00103                 return Corba::Expression::_duplicate( mexpr );
00104             return 0;
00105         }
00106 
00107         typename DataSource<T>::result_t value() const {
00108             return last_value;
00109         }
00110 
00111         virtual typename DataSource<T>::result_t get() const {
00112             CORBA::Any_var res = mexpr->get();
00113             ReferenceDataSource<T> rds(last_value);
00114             rds.ref();
00115             if ( rds.updateBlob(ORO_CORBA_PROTOCOL_ID, &res.in() ) == false)
00116                 Logger::log() <<Logger::Error << "Could not update CORBAExpression to remote value!"<<Logger::endl;
00117             return last_value;
00118         }
00119 
00120         virtual DataSource<T>* clone() const {
00121             return new CORBAExpression<T>( Corba::Expression::_duplicate( mexpr.in() ) );
00122         }
00123 
00124         virtual DataSource<T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00125             alreadyCloned[this] = const_cast<CORBAExpression<T>*>(this);
00126             return const_cast<CORBAExpression<T>*>(this);
00127         }
00128 
00129         virtual std::string getType() const {
00130             // both should be equivalent, but we display the local type.
00131             return DataSource<T>::GetType();
00132             //return std::string( mexpr->getType() );
00133         }
00134 
00135         virtual int serverProtocol() const
00136         {
00137             return ORO_CORBA_PROTOCOL_ID;
00138         }
00139     };
00140 
00144     template<>
00145     class CORBAExpression<void>
00146         : public DataSource<void>
00147     {
00148         Corba::Expression_var mexpr;
00149     public:
00150         CORBAExpression( Corba::Expression_ptr expr )
00151             : mexpr( Corba::Expression::_duplicate( expr ) )
00152         {
00153             assert( expr );
00154         }
00155 
00156         void* server(int p, void* arg)
00157         {
00158             if ( p == ORO_CORBA_PROTOCOL_ID)
00159                 return Corba::Expression::_duplicate( mexpr );
00160             return 0;
00161         }
00162 
00163         void* server(int p, void* arg) const
00164         {
00165             if ( p == ORO_CORBA_PROTOCOL_ID)
00166                 return Corba::Expression::_duplicate( mexpr );
00167             return 0;
00168         }
00169 
00170         void value() const {
00171         }
00172 
00173         virtual void get() const {
00174             // need var in order not to leak any...
00175             CORBA::Any_var res = mexpr->get();
00176         }
00177 
00178         virtual DataSource<void>* clone() const {
00179             return new CORBAExpression<void>( Corba::Expression::_duplicate( mexpr.in() ) );
00180         }
00181 
00182         virtual DataSource<void>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00183             alreadyCloned[this] = const_cast<CORBAExpression<void>*>(this);
00184             return const_cast<CORBAExpression<void>*>(this);
00185         }
00186 
00187         virtual int serverProtocol() const
00188         {
00189             return ORO_CORBA_PROTOCOL_ID;
00190         }
00191     };
00192 
00196     template<class T>
00197     class CORBAAssignableExpression
00198         : public AssignableDataSource<T>
00199     {
00200         typedef typename AssignableDataSource<T>::value_t value_t;
00201         Corba::AssignableExpression_var mexpr;
00202         typename AssignableDataSource<value_t>::shared_ptr storage;
00203         //mutable typename DataSource<T>::value_t last_value;
00204     public:
00205         CORBAAssignableExpression( Corba::AssignableExpression_ptr expr )
00206             : mexpr( Corba::AssignableExpression::_duplicate(expr) )//, last_value()
00207         {
00208             storage = detail::BuildType<value_t>::Value();
00209             assert( expr );
00210         }
00211 
00212         void* server(int p, void* arg)
00213         {
00214             if ( p == ORO_CORBA_PROTOCOL_ID)
00215                 return Corba::Expression::_duplicate( mexpr );
00216             return 0;
00217         }
00218 
00219         void* server(int p, void* arg) const
00220         {
00221             if ( p == ORO_CORBA_PROTOCOL_ID)
00222                 return Corba::Expression::_duplicate( mexpr );
00223             return 0;
00224         }
00225 
00226         typename DataSource<T>::result_t value() const {
00227             return storage->rvalue();
00228         }
00229 
00230         typename AssignableDataSource<T>::const_reference_t rvalue() const {
00231             return storage->rvalue();
00232         }
00233 
00234 
00235         virtual typename DataSource<T>::result_t get() const {
00236             CORBA::Any_var res = mexpr->get();
00237             ReferenceDataSource<T> rds( storage->set() );
00238             rds.ref();
00239             if ( rds.updateBlob(ORO_CORBA_PROTOCOL_ID, &res.in() ) == false)
00240                 Logger::log() <<Logger::Error << "Could not update CORBAAssignableExpression to remote value!"<<Logger::endl;
00241             return storage->rvalue();
00242         }
00243 
00244         virtual void set( typename AssignableDataSource<T>::param_t t ) {
00245             ValueDataSource<T> vds(t);
00246             vds.ref();
00247             CORBA::Any_var toset = (CORBA::Any_ptr)vds.createBlob(ORO_CORBA_PROTOCOL_ID);
00248             mexpr->set( toset.in() );
00249             storage->set( t );
00250         }
00251 
00252         virtual typename AssignableDataSource<T>::reference_t set() {
00253             return storage->set();
00254         }
00255 
00256         virtual void updated()
00257         {
00258             ValueDataSource<T> vds( storage->value() );
00259             vds.ref();
00260             CORBA::Any_var toset = (CORBA::Any_ptr)vds.createBlob(ORO_CORBA_PROTOCOL_ID);
00261             mexpr->set( toset.in() );
00262         }
00263 
00264         using AssignableDataSource<T>::update;
00265 
00266         virtual bool update(const CORBA::Any& any) {
00267             // send update and get result back.
00268             if ( mexpr->set( any ) ) {
00269                 this->get();
00270                 return true;
00271             }
00272             return false;
00273         }
00274 
00275         ::RTT::CommandInterface* updateCommand( DataSourceBase* other)
00276         {
00277             ::RTT::CommandInterface* ci = storage->updateCommand(other);
00278             if (ci)
00279                 return new CommandBinary( ci, new UpdatedCommand( this ) );
00280             return 0;
00281         }
00282 
00283         virtual ::RTT::CommandInterface* updatePartCommand(DataSourceBase* index, DataSourceBase* rhs )
00284         {
00285             ::RTT::CommandInterface* ci = storage->updatePartCommand(index, rhs);
00286             if (ci)
00287                 return new CommandBinary( ci, new UpdatedCommand( this ) );
00288             return 0;
00289         }
00290 
00291         virtual AssignableDataSource<T>* clone() const {
00292             return new CORBAAssignableExpression<T>( Corba::AssignableExpression::_duplicate( mexpr.in() ) );
00293         }
00294 
00295         virtual AssignableDataSource<T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00296             alreadyCloned[this] = const_cast<CORBAAssignableExpression<T>*>(this);
00297             return const_cast<CORBAAssignableExpression<T>*>(this);
00298         }
00299 
00300         virtual int serverProtocol() const
00301         {
00302             return ORO_CORBA_PROTOCOL_ID;
00303         }
00304     };
00305 
00306 }}
00307 
00308 #endif
Generated on Thu Dec 23 13:22:36 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3