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