CorbaDataObject.hpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef ORO_CORBA_DATAOBJECT_HPP
00041 #define ORO_CORBA_DATAOBJECT_HPP
00042
00043
00044 #include "../DataObjectInterfaces.hpp"
00045 #include "orbsvcs/CosEventChannelAdminC.h"
00046 #include "orbsvcs/CosEventChannelAdminS.h"
00047 #include "orbsvcs/CosEventCommC.h"
00048 #include "orbsvcs/CosEventCommS.h"
00049
00050 namespace RTT
00051 { namespace Corba {
00052
00053
00069 template<class T>
00070 class CorbaDataObject
00071 : public DataObjectInterface<T>
00072 {
00074 class CorbaDataObjectPushI
00075 : public virtual POA_CosEventComm::PushConsumer,
00076 public virtual PortableServer::RefCountServantBase
00077 {
00079 typename DataObjectInterface<T>::shared_ptr mimpl;
00080
00082 CosEventChannelAdmin::EventChannel_var mec;
00084 CosEventChannelAdmin::ProxyPushSupplier_var cproxy;
00085
00086 public:
00094 CorbaDataObjectPushI(typename DataObjectInterface<T>::shared_ptr impl, CosEventChannelAdmin::EventChannel_ptr ec )
00095 : mimpl(impl), mec(CosEventChannelAdmin::EventChannel::_duplicate(ec) )
00096 {
00097 log(Info) << "Creating Event Channel Push Consumer." << endlog();
00098
00099 CosEventChannelAdmin::ConsumerAdmin_var cadm = mec->for_consumers();
00100 cproxy = cadm->obtain_push_supplier();
00101 CosEventComm::PushConsumer_var puscon = POA_CosEventComm::PushConsumer::_this();
00102 cproxy->connect_push_consumer( puscon.in() );
00103 }
00104
00108 ~CorbaDataObjectPushI() {
00109 try {
00110 cproxy->disconnect_push_supplier();
00111 } catch(...) {}
00112 }
00113
00114 virtual void push (
00115 const ::CORBA::Any & data
00116 )
00117 ACE_THROW_SPEC ((
00118 CORBA::SystemException,
00119 ::CosEventComm::Disconnected
00120 ))
00121 {
00122 Logger::In in("CorbaDataObjectPushI::push");
00123 log(Debug) << "Accepting DataObject value."<<endlog();
00124 if ( mimpl->update( data ) == false) {
00125 Logger::log() <<Logger::Error << "Could not accept remote value: wrong data type."<<Logger::endl;
00126 return;
00127 }
00128 }
00129
00130 virtual void disconnect_push_consumer ()
00131 ACE_THROW_SPEC ((
00132 CORBA::SystemException
00133 ))
00134 {
00135
00136 }
00137
00138 };
00139
00141 class CorbaDataObjectPullI
00142 : public virtual POA_CosEventComm::PullSupplier,
00143 public virtual PortableServer::RefCountServantBase
00144 {
00146 typename DataObjectInterface<T>::shared_ptr mimpl;
00147
00149 CosEventChannelAdmin::EventChannel_var mec;
00151 CosEventChannelAdmin::ProxyPullConsumer_var sproxy;
00152
00153 public:
00161 CorbaDataObjectPullI(typename DataObjectInterface<T>::shared_ptr impl, CosEventChannelAdmin::EventChannel_ptr ec )
00162 : mimpl(impl), mec(CosEventChannelAdmin::EventChannel::_duplicate(ec) )
00163 {
00164 log(Info) << "Creating Event Channel Pull Supplier." << endlog();
00165
00166 CosEventChannelAdmin::SupplierAdmin_var sadm = mec->for_suppliers();
00167 sproxy = sadm->obtain_pull_consumer();
00168
00169 CosEventComm::PullSupplier_var pulsup = POA_CosEventComm::PullSupplier::_this();
00170 sproxy->connect_pull_supplier( pulsup.in() );
00171 }
00172
00176 ~CorbaDataObjectPullI() {
00177 log(Info) << "Destroying Event Channel Pull Supplier." << endlog();
00178 try {
00179 sproxy->disconnect_pull_consumer();
00180 } catch(...) {}
00181 }
00182
00186 virtual CORBA::Any * pull ()
00187 ACE_THROW_SPEC ((
00188 CORBA::SystemException,
00189 ::CosEventComm::Disconnected
00190 ))
00191 {
00192 Logger::In in("CorbaDataObjectPullI::pull");
00193 log(Debug) << "Returning DataObject value."<<endlog();
00194 ReferenceDataSource<T> rds( mimpl->Get() );
00195 rds.ref();
00196 CORBA::Any_var toset = (CORBA::Any_ptr)rds.createBlob(ORO_CORBA_PROTOCOL_ID );
00197 return toset._retn();
00198 }
00199
00203 virtual CORBA::Any * try_pull (
00204 ::CORBA::Boolean_out has_event
00205 )
00206 ACE_THROW_SPEC ((
00207 CORBA::SystemException,
00208 ::CosEventComm::Disconnected
00209 ))
00210 {
00211 Logger::In in("CorbaDataObjectPullI::try_pull");
00212 log(Debug) << "Returning DataObject value."<<endlog();
00213 has_event = 1;
00214 return this->pull();
00215 }
00216
00217 virtual void disconnect_pull_supplier ()
00218 ACE_THROW_SPEC ((
00219 CORBA::SystemException
00220 ))
00221 {
00222
00223 }
00224 };
00225
00226 CosEventComm::PullSupplier_var pull;
00227 CosEventComm::PushConsumer_var push;
00228
00230 typename DataObjectInterface<T>::shared_ptr mimpl;
00231
00233 CosEventChannelAdmin::EventChannel_var mec;
00234 public:
00242 CorbaDataObject(typename DataObjectInterface<T>::shared_ptr impl, CosEventChannelAdmin::EventChannel_ptr ec )
00243 : mimpl(impl), mec( CosEventChannelAdmin::EventChannel::_duplicate(ec) )
00244 {
00245 pull = (new CorbaDataObjectPullI(impl, ec ))->_this();
00246 push = (new CorbaDataObjectPushI(impl, ec ))->_this();
00247 }
00248
00252 ~CorbaDataObject() {
00253 }
00254
00255 CosEventComm::PullSupplier getPullSupplier() const {
00256 return CosEventComm::PullSupplier::_duplicate( pull );
00257 }
00258
00259 CosEventComm::PushConsumer getPushConsumer() const {
00260 return CosEventComm::PushConsumer::_duplicate( push );
00261 }
00262
00266 typedef T DataType;
00267
00268 virtual DataType Get() const { return mimpl->Get(); }
00269 virtual void Get(DataType& d) const { return mimpl->Get(d); }
00270 virtual void Set(const DataType& s) { return mimpl->Set(s); }
00271 virtual const std::string& getName() const {
00272 return mimpl->getName();
00273 }
00274
00275 CorbaDataObject<DataType>* clone() const {
00276 return new CorbaDataObject<DataType>( mimpl, mec.in() );
00277 }
00278
00279 CorbaDataObject<DataType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& ) const {
00280 return const_cast<CorbaDataObject<DataType>*>(this);
00281 }
00282
00283 };
00284
00285 }}
00286
00287 #endif
00288