00001 #!/usr/bin/env python 00002 # -*- coding: euc-jp -*- 00003 00004 ## 00005 # @file InPortPullConnector.py 00006 # @brief InPortPull type connector class 00007 # @date $Date$ 00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara 00009 # 00010 # Copyright (C) 2009 00011 # Noriaki Ando 00012 # Task-intelligence Research Group, 00013 # Intelligent Systems Research Institute, 00014 # National Institute of 00015 # Advanced Industrial Science and Technology (AIST), Japan 00016 # All rights reserved. 00017 # 00018 00019 from omniORB import * 00020 from omniORB import any 00021 00022 import OpenRTM_aist 00023 00024 00025 ## 00026 # @if jp 00027 # @class InPortPullConnector 00028 # @brief InPortPullConnector クラス 00029 # 00030 # InPort の pull 型データフローのための Connector クラス。このオブ 00031 # ジェクトは、接続時に dataflow_type に pull が指定された場合、 00032 # InPort によって生成・所有され、OutPortPullConnector と対になって、 00033 # データポートの pull 型のデータフローを実現する。一つの接続に対して、 00034 # 一つのデータストリームを提供する唯一の Connector が対応する。 00035 # Connector は 接続時に生成される UUID 形式の ID により区別される。 00036 # 00037 # InPortPullConnector は以下の三つのオブジェクトを所有し管理する。 00038 # 00039 # - InPortConsumer 00040 # - Buffer 00041 # 00042 # OutPort に書き込まれたデータは OutPortPullConnector::write() に渡 00043 # され Buffer に書き込まれる。InPort::read(), 00044 # InPortPullConnector::read() は結果として、OutPortConsumer::get() 00045 # を呼び出し、OutPortPullConnector の持つバッファからデータを読み出 00046 # し、InPortPullConnector のもつバッファにデータを書き込む。 00047 # 00048 # @since 1.0.0 00049 # 00050 # @else 00051 # @class InPortPullConnector 00052 # @brief InPortPullConnector class 00053 # 00054 # Connector class of InPort for pull type dataflow. When "pull" is 00055 # specified as dataflow_type at the time of establishing 00056 # connection, this object is generated and owned by the InPort. 00057 # This connector and InPortPullConnector make a pair and realize 00058 # pull type dataflow of data ports. One connector corresponds to 00059 # one connection which provides a data stream. Connector is 00060 # distinguished by ID of the UUID that is generated at establishing 00061 # connection. 00062 # 00063 # InPortPullConnector owns and manages the following objects. 00064 # 00065 # - InPortConsumer 00066 # - Buffer 00067 # 00068 # Data written into the OutPort is passed to the 00069 # OutPortPullConnector::write(), and is written into the buffer. 00070 # Consequently, InPort::read() and InPortPullConnector::read() call 00071 # OutPortConsumer::get(), and it reads data from the buffer of 00072 # OutPortPullConnector. Finally data would be written into the 00073 # InPortPullConnector's buffer. 00074 # 00075 # @since 1.0.0 00076 # 00077 # @endif 00078 # 00079 class InPortPullConnector(OpenRTM_aist.InPortConnector): 00080 """ 00081 """ 00082 00083 ## 00084 # @if jp 00085 # @brief コンストラクタ 00086 # 00087 # InPortPullConnector のコンストラクタはオブジェクト生成時に下記 00088 # を引数にとる。ConnectorInfo は接続情報を含み、この情報に従いバッ 00089 # ファ等を生成する。OutPort インターフェースのプロバイダオブジェク 00090 # トへのポインタを取り、所有権を持つので、InPortPullConnector は 00091 # OutPortConsumer の解体責任を持つ。各種イベントに対するコールバッ 00092 # ク機構を提供する ConnectorListeners を持ち、適切なタイミングでコー 00093 # ルバックを呼び出す。データバッファがもし InPortBase から提供さ 00094 # れる場合はそのポインタを取る。 00095 # 00096 # @param info ConnectorInfo 00097 # @param consumer OutPortConsumer 00098 # @param listeners ConnectorListeners 型のリスナオブジェクトリスト 00099 # @param buffer CdrBufferBase 型のバッファ 00100 # 00101 # @else 00102 # @brief Constructor 00103 # 00104 # InPortPullConnector's constructor is given the following 00105 # arguments. According to ConnectorInfo which includes 00106 # connection information, a buffer is created. It is also given 00107 # a pointer to the consumer object for the OutPort interface. 00108 # The owner-ship of the pointer is owned by this 00109 # OutPortPullConnector, it has responsibility to destruct the 00110 # OutPortConsumer. OutPortPullConnector also has 00111 # ConnectorListeners to provide event callback mechanisms, and 00112 # they would be called at the proper timing. If data buffer is 00113 # given by OutPortBase, the pointer to the buffer is also given 00114 # as arguments. 00115 # 00116 # @param info ConnectorInfo 00117 # @param consumer OutPortConsumer 00118 # @param listeners ConnectorListeners type lsitener object list 00119 # @param buffer CdrBufferBase type buffer 00120 # 00121 # @endif 00122 # 00123 # InPortPullConnector(ConnectorInfo info, 00124 # OutPortConsumer* consumer, 00125 # ConnectorListeners& listeners, 00126 # CdrBufferBase* buffer = 0); 00127 def __init__(self, info, consumer, listeners, buffer = 0): 00128 OpenRTM_aist.InPortConnector.__init__(self, info, buffer) 00129 self._consumer = consumer 00130 self._listeners = listeners 00131 if buffer == 0: 00132 self._buffer = self.createBuffer(self._profile) 00133 00134 if self._buffer == 0 or not self._consumer: 00135 raise 00136 00137 self._buffer.init(info.properties.getNode("buffer")) 00138 self._consumer.setBuffer(self._buffer) 00139 self._consumer.setListener(info, self._listeners) 00140 self.onConnect() 00141 return 00142 00143 00144 ## 00145 # @if jp 00146 # @brief デストラクタ 00147 # 00148 # disconnect() が呼ばれ、consumer, publisher, buffer が解体・削除される。 00149 # 00150 # @else 00151 # 00152 # @brief Destructor 00153 # 00154 # This operation calls disconnect(), which destructs and deletes 00155 # the consumer, the publisher and the buffer. 00156 # 00157 # @endif 00158 # 00159 def __del__(self): 00160 return 00161 00162 00163 ## 00164 # @if jp 00165 # @brief read 関数 00166 # 00167 # OutPortConsumer からデータを取得する。正常に読み出せた場合、戻り 00168 # 値は PORT_OK となり、data に読み出されたデータが格納される。それ 00169 # 以外の場合には、エラー値として BUFFER_EMPTY, TIMEOUT, 00170 # PRECONDITION_NOT_MET, PORT_ERROR が返される。 00171 # 00172 # @return PORT_OK 正常終了 00173 # BUFFER_EMPTY バッファは空である 00174 # TIMEOUT タイムアウトした 00175 # PRECONDITION_NOT_MET 事前条件を満たさない 00176 # PORT_ERROR その他のエラー 00177 # 00178 # @else 00179 # @brief Destructor 00180 # 00181 # This function get data from OutPortConsumer. If data is read 00182 # properly, this function will return PORT_OK return code. Except 00183 # normal return, BUFFER_EMPTY, TIMEOUT, PRECONDITION_NOT_MET and 00184 # PORT_ERROR will be returned as error codes. 00185 # 00186 # @return PORT_OK Normal return 00187 # BUFFER_EMPTY Buffer empty 00188 # TIMEOUT Timeout 00189 # PRECONDITION_NOT_MET Preconditin not met 00190 # PORT_ERROR Other error 00191 # 00192 # @endif 00193 # 00194 # virtual ReturnCode read(cdrMemoryStream& data); 00195 def read(self, data): 00196 self._rtcout.RTC_TRACE("InPortPullConnector.read()") 00197 if not self._consumer: 00198 return self.PORT_ERROR 00199 00200 cdr_data = [None] 00201 ret = self._consumer.get(cdr_data) 00202 00203 if ret == self.PORT_OK: 00204 # CDR -> (conversion) -> data 00205 if self._endian is not None: 00206 data[0] = cdrUnmarshal(any.to_any(data[0]).typecode(),cdr_data[0],self._endian) 00207 00208 else: 00209 self._rtcout.RTC_ERROR("unknown endian from connector") 00210 return OpenRTM_aist.BufferStatus.PRECONDITION_NOT_MET 00211 00212 return ret 00213 00214 00215 ## 00216 # @if jp 00217 # @brief 接続解除関数 00218 # 00219 # Connector が保持している接続を解除する 00220 # 00221 # @else 00222 # @brief Disconnect connection 00223 # 00224 # This operation disconnect this connection 00225 # 00226 # @endif 00227 # 00228 # virtual ReturnCode disconnect(); 00229 def disconnect(self): 00230 self._rtcout.RTC_TRACE("disconnect()") 00231 self.onDisconnect() 00232 # delete consumer 00233 if self._consumer: 00234 OpenRTM_aist.OutPortConsumerFactory.instance().deleteObject(self._consumer) 00235 self._consumer = 0 00236 00237 return self.PORT_OK 00238 00239 ## 00240 # @if jp 00241 # @brief アクティブ化 00242 # 00243 # このコネクタをアクティブ化する 00244 # 00245 # @else 00246 # 00247 # @brief Connector activation 00248 # 00249 # This operation activates this connector 00250 # 00251 # @endif 00252 # 00253 # virtual void activate(){}; // do nothing 00254 def activate(self): # do nothing 00255 pass 00256 00257 ## 00258 # @if jp 00259 # @brief 非アクティブ化 00260 # 00261 # このコネクタを非アクティブ化する 00262 # 00263 # @else 00264 # 00265 # @brief Connector deactivation 00266 # 00267 # This operation deactivates this connector 00268 # 00269 # @endif 00270 # 00271 # virtual void deactivate(){}; // do nothing 00272 def deactivate(self): # do nothing 00273 pass 00274 00275 ## 00276 # @if jp 00277 # @brief Bufferの生成 00278 # 00279 # 与えられた接続情報に基づきバッファを生成する。 00280 # 00281 # @param info 接続情報 00282 # @return バッファへのポインタ 00283 # 00284 # @else 00285 # @brief create buffer 00286 # 00287 # This function creates a buffer based on given information. 00288 # 00289 # @param info Connector information 00290 # @return The poitner to the buffer 00291 # 00292 # @endif 00293 # 00294 # CdrBufferBase* createBuffer(Profile& profile); 00295 def createBuffer(self, profile): 00296 buf_type = profile.properties.getProperty("buffer_type","ring_buffer") 00297 return OpenRTM_aist.CdrBufferFactory.instance().createObject(buf_type) 00298 00299 ## 00300 # @if jp 00301 # @brief 接続確立時にコールバックを呼ぶ 00302 # @else 00303 # @brief Invoke callback when connection is established 00304 # @endif 00305 # void onConnect() 00306 def onConnect(self): 00307 if self._listeners and self._profile: 00308 self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_CONNECT].notify(self._profile) 00309 return 00310 00311 ## 00312 # @if jp 00313 # @brief 接続切断時にコールバックを呼ぶ 00314 # @else 00315 # @brief Invoke callback when connection is destroied 00316 # @endif 00317 # void onDisconnect() 00318 def onDisconnect(self): 00319 if self._listeners and self._profile: 00320 self._listeners.connector_[OpenRTM_aist.ConnectorListenerType.ON_DISCONNECT].notify(self._profile) 00321 return