InPortBase.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 ##
00005 # @file InPortBase.py
00006 # @brief RTC::Port implementation for InPort
00007 # @date $Date: 2008-01-13 15:06:40 $
00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 #
00010 # Copyright (C) 2006-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 import copy
00020 import threading
00021 import OpenRTM_aist
00022 import RTC
00023 
00024 ##
00025 # @if jp
00026 # @namespace RTC
00027 #
00028 # @brief RTコンポーネント
00029 #
00030 # @else
00031 #
00032 # @namespace RTC
00033 #
00034 # @brief RT-Component
00035 #
00036 # @endif
00037 #
00038 
00039 ##
00040 # @if jp
00041 # @class InPortBase
00042 # @brief InPort 用 Port
00043 #
00044 # データ入力ポートの実装クラス。
00045 #
00046 # @since 0.4.0
00047 #
00048 # @else
00049 # @class InPortBase
00050 # @brief Port for InPort
00051 #
00052 # This is an implementation class for the data input port.
00053 #
00054 # @since 0.4.0
00055 #
00056 # @endif
00057 #
00058 class InPortBase(OpenRTM_aist.PortBase, OpenRTM_aist.DataPortStatus):
00059   """
00060   """
00061 
00062   ##
00063   # @if jp
00064   # @brief コンストラクタ
00065   #
00066   # コンストラクタ
00067   #
00068   # @param name ポート名称
00069   # @param inport 当該データ入力ポートに関連付けるInPortオブジェクト
00070   #               InPortオブジェクトで扱うデータ型、バッファタイプも指定する
00071   # @param prop ポート設定用プロパティ
00072   #
00073   # @else
00074   # @brief Constructor
00075   #
00076   # Constructor
00077   #
00078   # @param name Port name
00079   # @param inport InPort object that is associated with this data input port.
00080   #               Specify also the data type and the buffer type used in 
00081   #               the InPort object.
00082   # @param prop Property for setting ports
00083   #
00084   # @endif
00085   #
00086   # InPortBase(const char* name, const char* data_type);
00087   def __init__(self, name, data_type):
00088     OpenRTM_aist.PortBase.__init__(self,name)
00089     self._rtcout.RTC_DEBUG("Port name: %s", name)
00090     self._singlebuffer  = True
00091     self._thebuffer     = None
00092     self._properties    = OpenRTM_aist.Properties()
00093     self._providerTypes = ""
00094     self._consumerTypes = ""
00095     self._connectors    = []
00096     self._connector_mutex = threading.RLock()
00097 
00098     # PortProfile::properties を設定
00099     self._rtcout.RTC_DEBUG("setting port.port_type: DataInPort")
00100     self.addProperty("port.port_type", "DataInPort")
00101 
00102     self._rtcout.RTC_DEBUG("setting port.data_type: %s", data_type)
00103     self.addProperty("dataport.data_type", data_type)
00104 
00105     self.addProperty("dataport.subscription_type", "Any")
00106     self._value = None
00107     self._listeners = OpenRTM_aist.ConnectorListeners()
00108 
00109 
00110   ##
00111   # @if jp
00112   # @brief デストラクタ
00113   #
00114   # デストラクタ
00115   #
00116   # @else
00117   # @brief Destructor
00118   #
00119   # Destructor
00120   #
00121   # @endif
00122   #
00123   def __del__(self, PortBase=OpenRTM_aist.PortBase):
00124     self._rtcout.RTC_TRACE("InPortBase destructor")
00125 
00126     if len(self._connectors) != 0:
00127       self._rtcout.RTC_ERROR("connector.size should be 0 in InPortBase's dtor.")
00128       # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00129       for connector in self._connectors:
00130         connector.disconnect()
00131 
00132     if self._thebuffer is not None:
00133       OpenRTM_aist.CdrBufferFactory.instance().deleteObject(self._thebuffer)
00134       if not self._singlebuffer:
00135         self._rtcout.RTC_ERROR("Although singlebuffer flag is true, the buffer != 0")
00136 
00137     PortBase.__del__(self)
00138     return
00139 
00140 
00141   ##
00142   # @if jp
00143   # @brief プロパティの初期化
00144   #
00145   # 指定されたプロパティで初期化する。
00146   #
00147   # @param prop 設定するプロパティ
00148   # @else
00149   # @brief Initializing properties
00150   #
00151   # This method initializes the port in the specified property. 
00152   #
00153   # @param prop Property for setting ports
00154   # @endif
00155   #
00156   # void init(coil::Properties& prop);
00157   def init(self,prop):
00158     self._rtcout.RTC_TRACE("init()")
00159     self._properties.mergeProperties(prop)
00160     if self._singlebuffer:
00161       self._rtcout.RTC_DEBUG("single buffer mode.")
00162       self._thebuffer = OpenRTM_aist.CdrBufferFactory.instance().createObject("ring_buffer")
00163 
00164       if self._thebuffer is None:
00165         self._rtcout.RTC_ERROR("default buffer creation failed")
00166     else:
00167       self._rtcout.RTC_DEBUG("multi buffer mode.")
00168 
00169     self.initProviders()
00170     self.initConsumers()
00171 
00172     num = [-1]
00173     if not OpenRTM_aist.stringTo(num, self._properties.getProperty("connection_limit","-1")):
00174       self._rtcout.RTC_ERROR("invalid connection_limit value: %s",
00175                              self._properties.getProperty("connection_limit"))
00176 
00177     self.setConnectionLimit(num[0])
00178     return
00179 
00180 
00181   ##
00182   # @if jp
00183   # @brief RTObject_impl::readAll()から呼ばれる仮想関数
00184   #
00185   # DataPort からデータを読み出す
00186   #
00187   # @return true:成功,false:失敗
00188   # @else
00189   # @brief It is a virtual method that is called from RTObject_impl::readAll().
00190   # This method reads out data from DataPort. 
00191   #
00192   # @return true:Success,false:Failure
00193   # @endif
00194   #
00195   # virtual bool read() = 0;
00196   def read(self):
00197     pass
00198 
00199   ##
00200   # @if jp
00201   # @brief プロパティを取得する
00202   #
00203   # InPortのプロパティを取得する。
00204   #
00205   # @return プロパティ
00206   #
00207   # @else
00208   #
00209   # @brief Get properties
00210   #
00211   # Getting properties of this InPort
00212   #
00213   # @return InPort's properties
00214   #
00215   # @endif
00216   #
00217   def properties(self):
00218     self._rtcout.RTC_TRACE("properties()")
00219     return self._properties
00220 
00221 
00222   ##
00223   # @if jp
00224   # @brief Connector を取得
00225   #
00226   # 現在所有しているコネクタを取得する。
00227   #
00228   # @return connector のリスト
00229   #
00230   # @else
00231   #
00232   # @brief Connector list
00233   #
00234   # This operation returns connector list
00235   #
00236   # @return connector list
00237   #
00238   # @endif
00239   #
00240   # const std::vector<InPortConnector*>& connectors();
00241   def connectors(self):
00242     self._rtcout.RTC_TRACE("connectors(): size = %d", len(self._connectors))
00243     #  guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00244     return self._connectors
00245 
00246 
00247   ##
00248   # @if jp
00249   # @brief ConnectorProfile を取得
00250   #
00251   # 現在所有しているコネクタのProfileを取得する。
00252   #
00253   # @return ConnectorProfile のリスト
00254   #
00255   # @else
00256   #
00257   # @brief ConnectorProfile list
00258   #
00259   # This operation returns ConnectorProfile list
00260   #
00261   # @return connector list
00262   #
00263   # @endif
00264   #
00265   # ConnectorInfoList getConnectorProfiles();
00266   def getConnectorProfiles(self):
00267     self._rtcout.RTC_TRACE("getConnectorProfiles(): size = %d", len(self._connectors))
00268     profs = []
00269     #  guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00270     for con in self._connectors:
00271       profs.append(con.profile())
00272 
00273     return profs
00274         
00275   ##
00276   # @if jp
00277   # @brief ConnectorId を取得
00278   #
00279   # 現在所有しているコネクタのIDを取得する。
00280   #
00281   # @return ConnectorId のリスト
00282   #
00283   # @else
00284   #
00285   # @brief ConnectorId list
00286   #
00287   # This operation returns ConnectorId list
00288   #
00289   # @return connector list
00290   #
00291   # @endif
00292   #
00293   # coil::vstring getConnectorIds();
00294   def getConnectorIds(self):
00295     ids = []
00296 
00297     # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00298     for con in self._connectors:
00299       ids.append(con.id())
00300 
00301     self._rtcout.RTC_TRACE("getConnectorIds(): %s", OpenRTM_aist.flatten(ids))
00302     return ids
00303 
00304   ##
00305   # @if jp
00306   # @brief Connectorの名前を取得
00307   #
00308   # 現在所有しているコネクタの名前を取得する。
00309   #
00310   # @return Connector名のリスト
00311   #
00312   # @else
00313   #
00314   # @brief Connector name list
00315   #
00316   # This operation returns Connector name list
00317   #
00318   # @return connector name list
00319   #
00320   # @endif
00321   #
00322   # coil::vstring getConnectorNames();
00323   def getConnectorNames(self):
00324     names = []
00325     # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00326     for con in self._connectors:
00327       names.append(con.name())
00328 
00329     self._rtcout.RTC_TRACE("getConnectorNames(): %s", OpenRTM_aist.flatten(names))
00330     return names
00331 
00332   ##
00333   # @if jp
00334   # @brief ConnectorProfileをIDで取得
00335   #
00336   # 現在所有しているコネクタをIDで取得する。
00337   #
00338   # @param id Connector ID
00339   # @return コネクタへのポインタ
00340   #
00341   # @else
00342   #
00343   # @brief Getting ConnectorProfile by ID
00344   #
00345   # This operation returns Connector specified by ID.
00346   #
00347   # @param id Connector ID
00348   # @return A pointer to connector
00349   #
00350   # @endif
00351   #
00352   # InPortConnector* getConnectorById(const char* id);
00353   def getConnectorById(self, id):
00354     self._rtcout.RTC_TRACE("getConnectorById(id = %s)", id)
00355 
00356     for con in self._connectors:
00357       if id == con.id():
00358         return con
00359 
00360     self._rtcout.RTC_WARN("ConnectorProfile with the id(%s) not found.", id)
00361     return None
00362 
00363   ##
00364   # @if jp
00365   # @brief ConnectorProfileを名前で取得
00366   #
00367   # 現在所有しているコネクタを名前で取得する。
00368   #
00369   # @param name Connector name
00370   # @return コネクタへのポインタ
00371   #
00372   # @else
00373   #
00374   # @brief Getting Connector by name
00375   #
00376   # This operation returns Connector specified by name.
00377   #
00378   # @param id Connector ID
00379   # @return A pointer to connector
00380   #
00381   # @endif
00382   #
00383   # InPortConnector* getConnectorByName(const char* name);
00384   def getConnectorByName(self, name):
00385     self._rtcout.RTC_TRACE("getConnectorByName(name = %s)", name)
00386 
00387     for con in self._connectors:
00388       if name == con.name():
00389         return con
00390 
00391     self._rtcout.RTC_WARN("ConnectorProfile with the name(%s) not found.", name)
00392     return None
00393 
00394   ##
00395   # @if jp
00396   # @brief ConnectorProfileをIDで取得
00397   #
00398   # 現在所有しているコネクタをIDで取得する。
00399   #
00400   # @param id Connector ID
00401   # @param prof ConnectorProfile
00402   # @return false 指定したIDがない
00403   #
00404   # @else
00405   #
00406   # @brief Getting ConnectorProfile by name
00407   #
00408   # This operation returns ConnectorProfile specified by name
00409   #
00410   # @param id Connector ID
00411   # @param prof ConnectorProfile
00412   # @return false specified ID does not exist
00413   #
00414   # @endif
00415   #
00416   # bool getConnectorProfileById(const char* id,
00417   #                              ConnectorInfo& prof);
00418   def getConnectorProfileById(self, id, prof):
00419     self._rtcout.RTC_TRACE("getConnectorProfileById(id = %s)", id)
00420 
00421     # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00422     conn = self.getConnectorById(id)
00423     if not conn:
00424       return False
00425     prof[0] = conn.profile()
00426     return True
00427 
00428 
00429   ##
00430   # @if jp
00431   # @brief ConnectorProfileを名前で取得
00432   #
00433   # 現在所有しているコネクタを名前で取得する。
00434   #
00435   # @param name Connector name
00436   # @param prof ConnectorProfile
00437   # @return false 指定した名前がない
00438   #
00439   # @else
00440   #
00441   # @brief Getting ConnectorProfile by name
00442   #
00443   # This operation returns ConnectorProfile specified by name
00444   #
00445   # @param id Connector ID
00446   # @param prof ConnectorProfile
00447   # @return false specified name does not exist
00448   #
00449   # @endif
00450   #
00451   # bool getConnectorProfileByName(const char* name,
00452   #                                ConnectorInfo& prof);
00453   def getConnectorProfileByName(self, name, prof):
00454     self._rtcout.RTC_TRACE("getConnectorProfileByName(name = %s)", name)
00455 
00456     # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00457     conn = self.getConnectorByName(name)
00458     if not conn:
00459       return False
00460     prof[0] = conn.profile()
00461     return True
00462 
00463 
00464   ##
00465   # @if jp
00466   #
00467   # @brief [CORBA interface] Port の接続を行う
00468   #
00469   # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
00470   # する。この関数は主にアプリケーションプログラムやツールから呼び出
00471   # すことを前提としている。
00472   # 
00473   # @param connector_profile ConnectorProfile
00474   # @return ReturnCode_t 型のリターンコード
00475   #
00476   # @else
00477   #
00478   # @brief [CORBA interface] Connect the Port
00479   #
00480   # This operation establishes connection according to the given
00481   # ConnectionProfile inforamtion. This function is premised on
00482   # calling from mainly application program or tools.
00483   #
00484   # @param connector_profile The ConnectorProfile.
00485   # @return ReturnCode_t The return code of ReturnCode_t type.
00486   #
00487   # @endif
00488   #
00489   def connect(self, connector_profile):
00490     self._rtcout.RTC_TRACE("InPortBase.connect()")
00491         
00492     if OpenRTM_aist.NVUtil.find_index(connector_profile.properties,
00493                                       "dataport.serializer.cdr.endian") is -1:
00494       self._rtcout.RTC_TRACE("ConnectorProfile dataport.serializer.cdr.endian set.")
00495       connector_profile.properties.append(OpenRTM_aist.NVUtil.newNV("dataport.serializer.cdr.endian","little,big"))
00496 
00497     return OpenRTM_aist.PortBase.connect(self, connector_profile)
00498         
00499   ##
00500   # @if jp
00501   #
00502   # @brief InPortを activates する
00503   #
00504   # InPortを activate する。
00505   #
00506   # @else
00507   #
00508   # @brief Activate all Port interfaces
00509   #
00510   # This operation activate all interfaces that is registered in the
00511   # ports.
00512   #
00513   # @endif
00514   #
00515   # void activateInterfaces();
00516   def activateInterfaces(self):
00517     self._rtcout.RTC_TRACE("activateInterfaces()")
00518 
00519     # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00520     for connector in self._connectors:
00521       connector.activate()
00522       self._rtcout.RTC_DEBUG("activate connector: %s %s",
00523                              (connector.name(),connector.id()))
00524 
00525     return
00526 
00527 
00528   ##
00529   # @if jp
00530   #
00531   # @brief 全ての Port のインターフェースを deactivates する
00532   #
00533   # Port に登録されている全てのインターフェースを deactivate する。
00534   #
00535   # @else
00536   #
00537   # @brief Deactivate all Port interfaces
00538   #
00539   # This operation deactivate all interfaces that is registered in the
00540   # ports.
00541   #
00542   # @endif
00543   #
00544   # void deactivateInterfaces();
00545   def deactivateInterfaces(self):
00546     self._rtcout.RTC_TRACE("deactivateInterfaces()")
00547 
00548     # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00549     for connector in self._connectors:
00550       connector.deactivate()
00551       self._rtcout.RTC_DEBUG("deactivate connector: %s %s",
00552                              (connector.name(),connector.id()))
00553     return
00554 
00555 
00556   ##
00557   # @if jp
00558   # @brief ConnectorDataListener リスナを追加する
00559   #
00560   # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
00561   #
00562   # 設定できるリスナのタイプとコールバックイベントは以下の通り
00563   #
00564   # - ON_BUFFER_WRITE:          バッファ書き込み時
00565   # - ON_BUFFER_FULL:           バッファフル時
00566   # - ON_BUFFER_WRITE_TIMEOUT:  バッファ書き込みタイムアウト時
00567   # - ON_BUFFER_OVERWRITE:      バッファ上書き時
00568   # - ON_BUFFER_READ:           バッファ読み出し時
00569   # - ON_SEND:                  InProtへの送信時
00570   # - ON_RECEIVED:              InProtへの送信完了時
00571   # - ON_SEND_ERTIMEOUT:        OutPort側タイムアウト時
00572   # - ON_SEND_ERERROR:          OutPort側エラー時
00573   # - ON_RECEIVER_FULL:         InProt側バッファフル時
00574   # - ON_RECEIVER_TIMEOUT:      InProt側バッファタイムアウト時
00575   # - ON_RECEIVER_ERROR:        InProt側エラー時
00576   #
00577   # リスナは ConnectorDataListener を継承し、以下のシグニチャを持つ
00578   # operator() を実装している必要がある。
00579   #
00580   # ConnectorDataListener::
00581   #         operator()(const ConnectorProfile&, const cdrStream&)
00582   #
00583   # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
00584   # OutPortに移り、OutPort解体時もしくは、
00585   # removeConnectorDataListener() により削除時に自動的に解体される。
00586   # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
00587   # 数に false を指定し、自動的な解体を抑制することができる。
00588   #
00589   # @param listener_type リスナタイプ
00590   # @param listener リスナオブジェクトへのポインタ
00591   # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
00592   #
00593   # @else
00594   # @brief Adding BufferDataListener type listener
00595   #
00596   # This operation adds certain listeners related to buffer writing and
00597   # reading events.
00598   # The following listener types are available.
00599   #
00600   # - ON_BUFFER_WRITE:          At the time of buffer write
00601   # - ON_BUFFER_FULL:           At the time of buffer full
00602   # - ON_BUFFER_WRITE_TIMEOUT:  At the time of buffer write timeout
00603   # - ON_BUFFER_OVERWRITE:      At the time of buffer overwrite
00604   # - ON_BUFFER_READ:           At the time of buffer read
00605   # - ON_SEND:                  At the time of sending to InPort
00606   # - ON_RECEIVED:              At the time of finishing sending to InPort
00607   # - ON_SENDER_TIMEOUT:        At the time of timeout of OutPort
00608   # - ON_SENDER_ERROR:          At the time of error of OutPort
00609   # - ON_RECEIVER_FULL:         At the time of bufferfull of InPort
00610   # - ON_RECEIVER_TIMEOUT:      At the time of timeout of InPort
00611   # - ON_RECEIVER_ERROR:        At the time of error of InPort
00612   #
00613   # Listeners should have the following function operator().
00614   #
00615   # ConnectorDataListener::
00616   #         operator()(const ConnectorProfile&, const cdrStream&)
00617   #
00618   # The ownership of the given listener object is transferred to
00619   # this OutPort object in default.  The given listener object will
00620   # be destroied automatically in the OutPort's dtor or if the
00621   # listener is deleted by removeConnectorDataListener() function.
00622   # If you want to keep ownership of the listener object, give
00623   # "false" value to 3rd argument to inhibit automatic destruction.
00624   #
00625   # @param listener_type A listener type
00626   # @param listener A pointer to a listener object
00627   # @param autoclean A flag for automatic listener destruction
00628   #
00629   # @endif
00630   #
00631   # void 
00632   # addConnectorDataListener(ConnectorDataListenerType type,
00633   #                          ConnectorDataListener* listener,
00634   #                          bool autoclean)
00635   def addConnectorDataListener(self, listener_type, listener, autoclean = True):
00636     self._rtcout.RTC_TRACE("addConnectorDataListener()")
00637 
00638     if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
00639       self._listeners.connectorData_[listener_type].addListener(listener, autoclean)
00640       return
00641 
00642     self._rtcout.RTC_ERROR("addConnectorDataListener(): Invalid listener type.")
00643     return
00644 
00645 
00646   ##
00647   # @if jp
00648   # @brief ConnectorDataListener リスナを削除する
00649   #
00650   # 設定した各種リスナを削除する。
00651   # 
00652   # @param listener_type リスナタイプ
00653   # @param listener リスナオブジェクトへのポインタ
00654   #
00655   # @else
00656   # @brief Removing BufferDataListener type listener
00657   #
00658   # This operation removes a specified listener.
00659   #     
00660   # @param listener_type A listener type
00661   # @param listener A pointer to a listener object
00662   #
00663   # @endif
00664   #
00665   # void removeConnectorDataListener(ConnectorDataListenerType type,
00666   #                                  ConnectorDataListener* listener)
00667   def removeConnectorDataListener(self, listener_type, listener):
00668     self._rtcout.RTC_TRACE("removeConnectorDataListener()")
00669 
00670     if listener_type < OpenRTM_aist.ConnectorDataListenerType.CONNECTOR_DATA_LISTENER_NUM:
00671       self._listeners.connectorData_[listener_type].removeListener(listener)
00672       return
00673 
00674     self._rtcout.RTC_ERROR("removeConnectorDataListener(): Invalid listener type.")
00675     return
00676 
00677   
00678   ##
00679   # @if jp
00680   # @brief ConnectorListener リスナを追加する
00681   #
00682   # バッファ書き込みまたは読み出しイベントに関連する各種リスナを設定する。
00683   #
00684   # 設定できるリスナのタイプは
00685   #
00686   # - ON_BUFFER_EMPTY:       バッファが空の場合
00687   # - ON_BUFFER_READTIMEOUT: バッファが空でタイムアウトした場合
00688   #
00689   # リスナは以下のシグニチャを持つ operator() を実装している必要がある。
00690   #
00691   # ConnectorListener::operator()(const ConnectorProfile&)
00692   #
00693   # デフォルトでは、この関数に与えたリスナオブジェクトの所有権は
00694   # OutPortに移り、OutPort解体時もしくは、
00695   # removeConnectorListener() により削除時に自動的に解体される。
00696   # リスナオブジェクトの所有権を呼び出し側で維持したい場合は、第3引
00697   # 数に false を指定し、自動的な解体を抑制することができる。
00698   #
00699   # @param listener_type リスナタイプ
00700   # @param listener リスナオブジェクトへのポインタ
00701   # @param autoclean リスナオブジェクトの自動的解体を行うかどうかのフラグ
00702   #
00703   # @else
00704   # @brief Adding ConnectorListener type listener
00705   #
00706   # This operation adds certain listeners related to buffer writing and
00707   # reading events.
00708   # The following listener types are available.
00709   #
00710   # - ON_BUFFER_EMPTY:       At the time of buffer empty
00711   # - ON_BUFFER_READTIMEOUT: At the time of buffer read timeout
00712   #
00713   # Listeners should have the following function operator().
00714   #
00715   # ConnectorListener::operator()(const ConnectorProfile&)
00716   #  
00717   # The ownership of the given listener object is transferred to
00718   # this OutPort object in default.  The given listener object will
00719   # be destroied automatically in the OutPort's dtor or if the
00720   # listener is deleted by removeConnectorListener() function.
00721   # If you want to keep ownership of the listener object, give
00722   # "false" value to 3rd argument to inhibit automatic destruction.
00723   #
00724   # @param listener_type A listener type
00725   # @param listener A pointer to a listener object
00726   # @param autoclean A flag for automatic listener destruction
00727   #
00728   # @endif
00729   #
00730   # void addConnectorListener(ConnectorListenerType type,
00731   #                           ConnectorListener* listener,
00732   #                           bool autoclean)
00733   def addConnectorListener(self, listener_type, listener, autoclean = True):
00734     self._rtcout.RTC_TRACE("addConnectorListener()")
00735 
00736     if listener_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
00737       self._listeners.connector_[listener_type].addListener(listener, autoclean)
00738       return
00739 
00740     self._rtcout.RTC_ERROR("addConnectorListener(): Invalid listener type.")
00741     return
00742 
00743 
00744   ##
00745   # @if jp
00746   # @brief ConnectorDataListener リスナを削除する
00747   #
00748   # 設定した各種リスナを削除する。
00749   # 
00750   # @param listener_type リスナタイプ
00751   # @param listener リスナオブジェクトへのポインタ
00752   #
00753   # @else
00754   # @brief Removing BufferDataListener type listener
00755   #
00756   # This operation removes a specified listener.
00757   #     
00758   # @param listener_type A listener type
00759   # @param listener A pointer to a listener object
00760   #
00761   # @endif
00762   #
00763   # void removeConnectorListener(ConnectorListenerType type,
00764   #                              ConnectorListener* listener)
00765   def removeConnectorListener(self, listener_type, listener):
00766     self._rtcout.RTC_TRACE("removeConnectorListener()")
00767         
00768     if listener_type < OpenRTM_aist.ConnectorListenerType.CONNECTOR_LISTENER_NUM:
00769       self._listeners.connector_[listener_type].removeListener(listener)
00770       return
00771 
00772     self._rtcout.RTC_ERROR("removeConnectorListener(): Invalid listener type.")
00773     return
00774 
00775 
00776   ##
00777   # @if jp
00778   # @brief Interface情報を公開する
00779   #
00780   # Interface情報を公開する。
00781   # 引数の ConnectorProfile に格納されている dataflow_type が push 型
00782   # の場合は、指定された interface_type の InPortProvider に関する情報
00783   # を ConnectorProfile::properties に書込み呼び出し側に戻す。
00784   #
00785   #  dataport.dataflow_type
00786   #
00787   # @param connector_profile コネクタプロファイル
00788   #
00789   # @return ReturnCode_t 型のリターンコード
00790   #
00791   # @else
00792   # @brief Publish interface information
00793   #
00794   # Publish interface information.
00795   # Assign the Provider information that owned by this port
00796   # to ConnectorProfile#properties
00797   #
00798   # @param connector_profile The connector profile
00799   #
00800   # @return The return code of ReturnCode_t type
00801   #
00802   # @endif
00803   #
00804   # ReturnCode_t publishInterfaces(ConnectorProfile& connector_profile);
00805   def publishInterfaces(self, cprof):
00806     self._rtcout.RTC_TRACE("publishInterfaces()")
00807 
00808     retval = self._publishInterfaces()
00809     if retval != RTC.RTC_OK:
00810       return retval
00811 
00812     # prop: [port.outport].
00813     prop = copy.deepcopy(self._properties)
00814 
00815     conn_prop = OpenRTM_aist.Properties()
00816     OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
00817     prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
00818 
00819     # marge ConnectorProfile for buffer property.
00820     prop.mergeProperties(conn_prop.getNode("dataport.inport"))
00821 
00822     #
00823     # ここで, ConnectorProfile からの properties がマージされたため、
00824     # prop["dataflow_type"]: データフロータイプ
00825     # prop["interface_type"]: インターフェースタイプ
00826     # などがアクセス可能になる。
00827     #
00828     dflow_type = prop.getProperty("dataflow_type")
00829     dflow_type = OpenRTM_aist.normalize([dflow_type])
00830 
00831     if dflow_type == "push":
00832       self._rtcout.RTC_DEBUG("dataflow_type = push .... create PushConnector")
00833 
00834       # create InPortProvider
00835       provider = self.createProvider(cprof, prop)
00836 
00837       if not provider:
00838         self._rtcout.RTC_ERROR("InPort provider creation failed.")
00839         return RTC.BAD_PARAMETER
00840 
00841       # create InPortPushConnector
00842       connector = self.createConnector(cprof, prop, provider_=provider)
00843       if not connector:
00844         self._rtcout.RTC_ERROR("PushConnector creation failed.")
00845         return RTC.RTC_ERROR
00846 
00847       connector.setDataType(self._value)
00848       provider.setConnector(connector) # So that a provider gets endian information from a connector.
00849 
00850       self._rtcout.RTC_DEBUG("publishInterfaces() successfully finished.")
00851       return RTC.RTC_OK
00852 
00853     elif dflow_type == "pull":
00854       self._rtcout.RTC_DEBUG("dataflow_type = pull .... do nothing")
00855       return RTC.RTC_OK
00856 
00857     self._rtcout.RTC_ERROR("unsupported dataflow_type")
00858     return RTC.BAD_PARAMETER
00859 
00860     
00861   ##
00862   # @if jp
00863   # @brief Interfaceに接続する
00864   #
00865   # Interfaceに接続する。
00866   # Portが所有するConsumerに適合するProviderに関する情報を 
00867   # ConnectorProfile#properties から抽出し、
00868   # ConsumerにCORBAオブジェクト参照を設定する。
00869   #
00870   # @param connector_profile コネクタ・プロファイル
00871   #
00872   # @return ReturnCode_t 型のリターンコード
00873   #
00874   # @else
00875   # @brief Subscribe to the interface
00876   #
00877   # Subscribe to interface.
00878   # Derive Provider information that matches Consumer owned by the Port 
00879   # from ConnectorProfile#properties and 
00880   # set the Consumer to the reference of the CORBA object.
00881   #
00882   # @param connector_profile The connector profile
00883   #
00884   # @return ReturnCode_t The return code of ReturnCode_t type
00885   #
00886   # @endif
00887   #
00888   # ReturnCode_t subscribeInterfaces(const ConnectorProfile& connector_profile);
00889   def subscribeInterfaces(self, cprof):
00890     self._rtcout.RTC_TRACE("subscribeInterfaces()")
00891 
00892     # prop: [port.outport].
00893     prop = copy.deepcopy(self._properties)
00894     conn_prop = OpenRTM_aist.Properties()
00895     OpenRTM_aist.NVUtil.copyToProperties(conn_prop, cprof.properties)
00896     prop.mergeProperties(conn_prop.getNode("dataport")) # marge ConnectorProfile
00897     prop.mergeProperties(conn_prop.getNode("dataport.inport")) # marge ConnectorProfile for buffer property.
00898     
00899     #
00900     # ここで, ConnectorProfile からの properties がマージされたため、
00901     # prop["dataflow_type"]: データフロータイプ
00902     # prop["interface_type"]: インターフェースタイプ
00903     # などがアクセス可能になる。
00904     #
00905     dflow_type = prop.getProperty("dataflow_type")
00906     dtype = [dflow_type]
00907     OpenRTM_aist.normalize(dtype)
00908     dflow_type = dtype[0]
00909     
00910     profile = OpenRTM_aist.ConnectorInfo(cprof.name,
00911                                          cprof.connector_id,
00912                                          OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
00913                                          prop)
00914     if dflow_type == "push":
00915       self._rtcout.RTC_DEBUG("dataflow_type = push .... do nothing")
00916 
00917       conn = self.getConnectorById(cprof.connector_id)
00918 
00919       if not conn:
00920         self._rtcout.RTC_ERROR("specified connector not found: %s",
00921                                cprof.connector_id)
00922         return RTC.RTC_ERROR
00923 
00924       ret = conn.setConnectorInfo(profile)
00925       if ret == RTC.RTC_OK:
00926         self._rtcout.RTC_DEBUG("subscribeInterfaces() successfully finished.")
00927 
00928       return ret
00929 
00930     elif dflow_type == "pull":
00931       self._rtcout.RTC_DEBUG("dataflow_type = pull .... create PullConnector")
00932 
00933       # create OutPortConsumer
00934       consumer = self.createConsumer(cprof, prop)
00935       if not consumer:
00936         return RTC.BAD_PARAMETER
00937 
00938       # create InPortPullConnector
00939       connector = self.createConnector(cprof, prop, consumer_=consumer)
00940       if not connector:
00941         return RTC.RTC_ERROR
00942 
00943       ret = connector.setConnectorInfo(profile)
00944 
00945       if ret == RTC.RTC_OK:
00946         self._rtcout.RTC_DEBUG("publishInterface() successfully finished.")
00947 
00948       return ret
00949 
00950     self._rtcout.RTC_ERROR("unsupported dataflow_type")
00951     return RTC.BAD_PARAMETER
00952         
00953     
00954   ##
00955   # @if jp
00956   # @brief Interfaceへの接続を解除する
00957   #
00958   # Interfaceへの接続を解除する。
00959   # 与えられたConnectorProfileに関連するConsumerに設定された全てのObjectを
00960   # 解放し接続を解除する。
00961   #
00962   # @param connector_profile コネクタ・プロファイル
00963   #
00964   # @else
00965   # @brief Disconnect the interface connection
00966   #
00967   # Disconnect the interface connection.
00968   # Release all objects set in Consumer associated with 
00969   # given ConnectorProfile and unscribe the interface.
00970   #
00971   # @param connector_profile The connector profile
00972   #
00973   # @endif
00974   #
00975   # void unsubscribeInterfaces(const ConnectorProfile& connector_profile);
00976   def unsubscribeInterfaces(self, connector_profile):
00977     self._rtcout.RTC_TRACE("unsubscribeInterfaces()")
00978     
00979     id = connector_profile.connector_id
00980     self._rtcout.RTC_PARANOID("connector_id: %s", id)
00981 
00982     len_ = len(self._connectors)
00983     for i in range(len_):
00984       idx = (len_ - 1) - i
00985       # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
00986       if id == self._connectors[idx].id():
00987         # Connector's dtor must call disconnect()
00988         self._connectors[idx].deactivate()
00989         self._connectors[idx].disconnect()
00990         del self._connectors[idx]
00991         self._rtcout.RTC_TRACE("delete connector: %s", id)
00992         return
00993 
00994     self._rtcout.RTC_ERROR("specified connector not found: %s", id)
00995     return
00996 
00997 
00998   ##
00999   # @if jp
01000   # @brief InPort provider の初期化
01001   # @else
01002   # @brief InPort provider initialization
01003   # @endif
01004   #
01005   # void initProviders();
01006   def initProviders(self):
01007     self._rtcout.RTC_TRACE("initProviders()")
01008 
01009     # create InPort providers
01010     factory = OpenRTM_aist.InPortProviderFactory.instance()
01011     provider_types = factory.getIdentifiers()
01012 
01013     self._rtcout.RTC_DEBUG("available providers: %s",
01014                            OpenRTM_aist.flatten(provider_types))
01015 
01016     if self._properties.hasKey("provider_types") and \
01017           OpenRTM_aist.normalize(self._properties.getProperty("provider_types")) != "all":
01018       self._rtcout.RTC_DEBUG("allowed providers: %s",
01019                              self._properties.getProperty("provider_types"))
01020 
01021       temp_types = provider_types
01022       provider_types = []
01023       active_types = OpenRTM_aist.split(self._properties.getProperty("provider_types"), ",")
01024 
01025       temp_types.sort()
01026       active_types.sort()
01027 
01028       set_ptypes = set(temp_types).intersection(set(active_types))
01029       provider_types = provider_types + list(set_ptypes)
01030 
01031     # InPortProvider supports "push" dataflow type
01032     if len(provider_types) > 0:
01033       self._rtcout.RTC_DEBUG("dataflow_type push is supported")
01034       self.appendProperty("dataport.dataflow_type", "push")
01035       self.appendProperty("dataport.interface_type",
01036                           OpenRTM_aist.flatten(provider_types))
01037 
01038     self._providerTypes = provider_types
01039     return
01040 
01041 
01042   ##
01043   # @if jp
01044   # @brief OutPort consumer の初期化
01045   # @else
01046   # @brief OutPort consumer initialization
01047   # @endif
01048   #
01049   # void initConsumers();
01050   def initConsumers(self):
01051     self._rtcout.RTC_TRACE("initConsumers()")
01052 
01053     # create OuPort consumers
01054     factory = OpenRTM_aist.OutPortConsumerFactory.instance()
01055     consumer_types = factory.getIdentifiers()
01056     self._rtcout.RTC_DEBUG("available consumers: %s",
01057                            OpenRTM_aist.flatten(consumer_types))
01058 
01059     if self._properties.hasKey("consumer_types") and \
01060           OpenRTM_aist.normalize(self._properties.getProperty("consumer_types")) != "all":
01061       self._rtcout.RTC_DEBUG("allowed consumers: %s",
01062                              self._properties.getProperty("consumer_types"))
01063 
01064       temp_types = consumer_types
01065       consumer_types = []
01066       active_types = OpenRTM_aist.split(self._properties.getProperty("consumer_types"), ",")
01067 
01068       temp_types.sort()
01069       active_types.sort()
01070 
01071       set_ctypes = set(temp_types).intersection(set(active_types))
01072       consumer_types = consumer_types + list(set_ctypes)
01073 
01074     # OutPortConsumer supports "pull" dataflow type
01075     if len(consumer_types) > 0:
01076       self._rtcout.RTC_PARANOID("dataflow_type pull is supported")
01077       self.appendProperty("dataport.dataflow_type", "pull")
01078       self.appendProperty("dataport.interface_type",
01079                           OpenRTM_aist.flatten(consumer_types))
01080 
01081     self._consumerTypes = consumer_types
01082     return
01083 
01084 
01085   ##
01086   # @if jp
01087   # @brief InPort provider の生成
01088   #
01089   # InPortProvider を生成し、情報を ConnectorProfile に公開する。
01090   # 生成に失敗した場合 0 を返す。
01091   #
01092   # @else
01093   # @brief InPort provider creation
01094   # @endif
01095   #
01096   # InPortProvider*
01097   # createProvider(ConnectorProfile& cprof, coil::Properties& prop);
01098   def createProvider(self, cprof, prop):
01099     if not prop.getProperty("interface_type") and \
01100           not OpenRTM_aist.includes(self._providerTypes, prop.getProperty("interface_type")):
01101       self._rtcout.RTC_ERROR("no provider found")
01102       self._rtcout.RTC_DEBUG("interface_type:  %s", prop.getProperty("interface_type"))
01103       self._rtcout.RTC_DEBUG("interface_types: %s",
01104                              OpenRTM_aist.flatten(self._providerTypes))
01105       return 0
01106 
01107     
01108     self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
01109     provider = OpenRTM_aist.InPortProviderFactory.instance().createObject(prop.getProperty("interface_type"))
01110     
01111     if provider != 0:
01112       self._rtcout.RTC_DEBUG("provider created")
01113       provider.init(prop.getNode("provider"))
01114 
01115       if not provider.publishInterface(cprof.properties):
01116         self._rtcout.RTC_ERROR("publishing interface information error")
01117         OpenRTM_aist.InPortProviderFactory.instance().deleteObject(provider)
01118         return 0
01119       return provider
01120 
01121     self._rtcout.RTC_ERROR("provider creation failed")
01122     return 0
01123 
01124 
01125   ##
01126   # @if jp
01127   # @brief OutPort consumer の生成
01128   #
01129   # OutPortConsumer を生成する。
01130   # 生成に失敗した場合 0 を返す。
01131   #
01132   # @else
01133   # @brief InPort provider creation
01134   # @endif
01135   #
01136   # OutPortConsumer*
01137   # createConsumer(const ConnectorProfile& cprof, coil::Properties& prop);
01138   def createConsumer(self, cprof, prop):
01139     if not prop.getProperty("interface_type") and \
01140           not OpenRTM_aist.includes(self._consumerTypes, prop.getProperty("interface_type")):
01141       self._rtcout.RTC_ERROR("no consumer found")
01142       self._rtcout.RTC_DEBUG("interface_type:  %s", prop.getProperty("interface_type"))
01143       self._rtcout.RTC_DEBUG("interface_types: %s",
01144                              OpenRTM_aist.flatten(self._consumerTypes))
01145       return 0
01146     
01147     self._rtcout.RTC_DEBUG("interface_type: %s", prop.getProperty("interface_type"))
01148     consumer = OpenRTM_aist.OutPortConsumerFactory.instance().createObject(prop.getProperty("interface_type"))
01149     
01150     if consumer != 0:
01151       self._rtcout.RTC_DEBUG("consumer created")
01152       consumer.init(prop.getNode("consumer"))
01153 
01154       if not consumer.subscribeInterface(cprof.properties):
01155         self._rtcout.RTC_ERROR("interface subscription failed.")
01156         OpenRTM_aist.OutPortConsumerFactory.instance().deleteObject(consumer)
01157         return 0
01158       return consumer
01159 
01160     self._rtcout.RTC_ERROR("consumer creation failed")
01161     return 0
01162 
01163 
01164   ##
01165   # @if jp
01166   # @brief InPortPushConnector の生成
01167   #
01168   # Connector を生成し、生成が成功すれば m_connectors に保存する。
01169   # 生成に失敗した場合 0 を返す。
01170   #
01171   # @else
01172   # @brief InPortPushConnector creation
01173   # @endif
01174   #
01175   # InPortConnector*
01176   #  createConnector(ConnectorProfile& cprof, coil::Properties& prop,
01177   #                  InPortProvider* provider);
01178   def createConnector(self, cprof, prop, provider_=None, consumer_=None):
01179     profile = OpenRTM_aist.ConnectorInfo(cprof.name,
01180                                          cprof.connector_id,
01181                                          OpenRTM_aist.CORBA_SeqUtil.refToVstring(cprof.ports),
01182                                          prop)
01183     connector = None
01184 
01185 
01186     try:
01187       if provider_ is not None:
01188         if self._singlebuffer:
01189           connector = OpenRTM_aist.InPortPushConnector(profile, provider_,
01190                                                        self._listeners,
01191                                                        self._thebuffer)
01192         else:
01193           connector = OpenRTM_aist.InPortPushConnector(profile, provider_,
01194                                                        self._listeners)
01195 
01196       elif consumer_ is not None:
01197         if self._singlebuffer:
01198           connector = OpenRTM_aist.InPortPullConnector(profile, consumer_,
01199                                                        self._listeners,
01200                                                        self._thebuffer)
01201         else:
01202           connector = OpenRTM_aist.InPortPullConnector(profile, consumer_,
01203                                                        self._listeners)
01204 
01205       else:
01206         self._rtcout.RTC_ERROR("provider or consumer is not passed. returned 0;")
01207         return 0
01208                 
01209 
01210       if connector is None:
01211         self._rtcout.RTC_ERROR("InPortConnector creation failed")
01212         return 0
01213 
01214       if provider_ is not None:
01215         self._rtcout.RTC_TRACE("InPortPushConnector created")
01216       elif consumer_ is not None:
01217         self._rtcout.RTC_TRACE("InPortPullConnector created")
01218 
01219       # guard = OpenRTM_aist.ScopedLock(self._connector_mutex)
01220       self._connectors.append(connector)
01221       self._rtcout.RTC_PARANOID("connector push backed: %d", len(self._connectors))
01222       return connector
01223     except:
01224       self._rtcout.RTC_ERROR("InPortPushConnector creation failed")
01225       self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
01226       return 0
01227 
01228     self._rtcout.RTC_FATAL("never comes here: createConnector()")
01229     return 0


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Thu Aug 27 2015 14:17:28