PortBase.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 ##
00005 # @file PortBase.py
00006 # @brief RTC's Port base class
00007 # @date $Date: 2007/09/18 $
00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 #
00010 # Copyright (C) 2006-2008
00011 #     Task-intelligence Research Group,
00012 #     Intelligent Systems Research Institute,
00013 #     National Institute of
00014 #         Advanced Industrial Science and Technology (AIST), Japan
00015 #     All rights reserved.
00016 
00017 
00018 import threading
00019 import copy
00020 
00021 import OpenRTM_aist
00022 import RTC, RTC__POA
00023 
00024 
00025 
00026 ##
00027 # @if jp
00028 # @class PortBase
00029 # @brief Port の基底クラス
00030 #
00031 # RTC::Port の基底となるクラス。
00032 # RTC::Port はほぼ UML Port の概念を継承しており、ほぼ同等のものとみなす
00033 # ことができる。RT コンポーネントのコンセプトにおいては、
00034 # Port はコンポーネントに付属し、コンポーネントが他のコンポーネントと相互作用
00035 # を行う接点であり、通常幾つかのインターフェースと関連付けられる。
00036 # コンポーネントは Port を通して外部に対しインターフェースを提供または要求
00037 # することができ、Portはその接続を管理する役割を担う。
00038 # <p>
00039 # Port の具象クラスは、通常 RT コンポーネントインスタンス生成時に同時に
00040 # 生成され、提供・要求インターフェースを登録した後、RT コンポーネントに
00041 # 登録され、外部からアクセス可能な Port として機能することを想定している。
00042 # <p>
00043 # RTC::Port は CORBA インターフェースとして以下のオペレーションを提供する。
00044 #
00045 # - get_port_profile()
00046 # - get_connector_profiles()
00047 # - get_connector_profile()
00048 # - connect()
00049 # - notify_connect()
00050 # - disconnect()
00051 # - notify_disconnect()
00052 # - disconnect_all()
00053 #
00054 # このクラスでは、これらのオペレーションの実装を提供する。
00055 # <p>
00056 # これらのオペレーションのうち、get_port_profile(), get_connector_profiles(),
00057 # get_connector_profile(), connect(), disconnect(), disconnect_all() は、
00058 # サブクラスにおいて特に振る舞いを変更する必要がないため、オーバーライド
00059 # することは推奨されない。
00060 # <p>
00061 # notify_connect(), notify_disconnect() については、サブクラスが提供・要求
00062 # するインターフェースの種類に応じて、振る舞いを変更する必要が生ずる
00063 # かもしれないが、これらを直接オーバーライドすることは推奨されず、
00064 # 後述の notify_connect(), notify_disconnect() の項においても述べられる通り
00065 # これらの関数に関連した 関数をオーバーライドすることにより振る舞いを変更する
00066 # ことが推奨される。
00067 #
00068 # @since 0.4.0
00069 #
00070 # @else
00071 # @class PortBase
00072 # @brief Port base class
00073 #
00074 # This class is a base class of RTC::Port.
00075 # RTC::Port inherits a concept of RT-Component, and can be regarded as almost
00076 # the same as it. In the concept of RT-Component, Port is attached to the
00077 # component, can mediate interaction between other components and usually is
00078 # associated with some interfaces.
00079 # Component can provide or require interface for outside via Port, and the
00080 # Port plays a role to manage the connection.
00081 # <p>
00082 # Concrete class of Port assumes to be usually created at the same time that
00083 # RT-Component's instance is created, be registerd to RT-Component after
00084 # provided and required interfaces are registerd, and function as accessible
00085 # Port from outside.
00086 # <p>
00087 # RTC::Port provides the following operations as CORBA interface:
00088 #
00089 # - get_port_profile()
00090 # - get_connector_profiles()
00091 # - get_connector_profile()
00092 # - connect()
00093 # - notify_connect()
00094 # - disconnect()
00095 # - notify_disconnect()
00096 # - disconnect_all()
00097 #
00098 # This class provides implementations of these operations.
00099 # <p>
00100 # In these operations, as for get_port_profile(), get_connector_profiles(),
00101 # get_connector_profile(), connect(), disconnect() and disconnect_all(),
00102 # since their behaviors especially need not to be change in subclass, 
00103 # overriding is not recommended.
00104 # <p>
00105 # As for notify_connect() and notify_disconnect(), you may have to modify
00106 # behavior according to the kind of interfaces that subclass provides and
00107 # requires, however it is not recommended these are overriden directly.
00108 # In the section of notify_connect() and notify_disconnect() as described
00109 # below, it is recommended that you modify behavior by overriding the
00110 # protected function related to these functions.
00111 #
00112 # @since 0.4.0
00113 #
00114 # @endif
00115 class PortBase(RTC__POA.PortService):
00116   """
00117   """
00118 
00119 
00120 
00121   ##
00122   # @if jp
00123   # @brief コンストラクタ
00124   #
00125   # PortBase のコンストラクタは Port 名 name を引数に取り初期化を行う
00126   # と同時に、自分自身を CORBA Object として活性化し、自身の PortProfile
00127   # の port_ref に自身のオブジェクトリファレンスを格納する。
00128   # 名前には、"." 以外の文字列を使用することができる。
00129   #
00130   # @param self
00131   # @param name Port の名前(デフォルト値:None)
00132   #
00133   # @else
00134   #
00135   # @brief Constructor
00136   #
00137   # The constructor of the ProtBase class is given the name of this Port
00138   # and initialized. At the same time, the PortBase activates itself
00139   # as CORBA object and stores its object reference to the PortProfile's 
00140   # port_ref member.
00141   # Characters except "." can be used for the name of the port.
00142   #
00143   # @param name The name of Port 
00144   #
00145   # @endif
00146   def __init__(self, name=None):
00147     self._ownerInstanceName = "unknown"
00148     self._objref = self._this()
00149 
00150     self._profile = RTC.PortProfile("", [], RTC.PortService._nil, [], RTC.RTObject._nil,[])
00151     # Now Port name is <instance_name>.<port_name>. r1648
00152     if name is None:
00153       self._profile.name = "unknown.unknown"
00154     else:
00155       self._profile.name = self._ownerInstanceName+"."+name
00156       
00157     self._profile.port_ref = self._objref
00158     self._profile.owner = RTC.RTObject._nil
00159     self._profile_mutex = threading.RLock()
00160     self._connection_mutex = threading.RLock()
00161     self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf(name)
00162     self._onPublishInterfaces = None
00163     self._onSubscribeInterfaces = None
00164     self._onConnected = None
00165     self._onUnsubscribeInterfaces = None
00166     self._onDisconnected = None
00167     self._onConnectionLost = None
00168     self._connectionLimit   = -1
00169     self._portconnListeners = None
00170     return
00171 
00172   
00173   ##
00174   # @if jp
00175   #
00176   # @brief デストラクタ
00177   #
00178   # デストラクタでは、PortService CORBA オブジェクトの deactivate を
00179   # 行う。deactivateに際して例外を投げることはない。
00180   #
00181   # @else
00182   #
00183   # @brief Destructor
00184   #
00185   # In the destructor, PortService CORBA object is deactivated.
00186   # This function never throws exception.
00187   #
00188   # @endif
00189   #
00190   def __del__(self):
00191     self._rtcout.RTC_TRACE("PortBase.__del__()")
00192     try:
00193       mgr = OpenRTM_aist.Manager.instance().getPOA()
00194       oid = mgr.servant_to_id(self)
00195       mgr.deactivate_object(oid)
00196     except:
00197       self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
00198     
00199 
00200   ##
00201   # @if jp
00202   #
00203   # @brief [CORBA interface] PortProfileを取得する
00204   #
00205   # Portが保持するPortProfileを返す。
00206   # PortProfile 構造体は以下のメンバーを持つ。
00207   #
00208   # - name              [string 型] Port の名前。
00209   # - interfaces        [PortInterfaceProfileList 型] Port が保持する
00210   #                     PortInterfaceProfile のシーケンス
00211   # - port_ref          [Port Object 型] Port 自身のオブジェクトリファレンス
00212   # - connector_profile [ConnectorProfileList 型] Port が現在保持する
00213   #                     ConnectorProfile のシーケンス
00214   # - owner             [RTObject Object 型] この Port を所有する
00215   #                     RTObjectのリファレンス
00216   # - properties        [NVList 型] その他のプロパティ。
00217   #
00218   # @param self
00219   #
00220   # @return PortProfile
00221   #
00222   # @else
00223   #
00224   # @brief [CORBA interface] Get the PortProfile of the Port
00225   #
00226   # This operation returns the PortProfile of the Port.
00227   # PortProfile struct has the following members,
00228   #
00229   # - name              [string ] The name of the Port.
00230   # - interfaces        [PortInterfaceProfileList] The sequence of 
00231   #                     PortInterfaceProfile owned by the Port
00232   # - port_ref          [Port Object] The object reference of the Port.
00233   # - connector_profile [ConnectorProfileList] The sequence of 
00234   #                     ConnectorProfile owned by the Port.
00235   # - owner             [RTObject Object] The object reference of 
00236   #                     RTObject that is owner of the Port.
00237   # - properties        [NVList] The other properties.
00238   #
00239   # @return the PortProfile of the Port
00240   #
00241   # @endif
00242   # PortProfile* get_port_profile()
00243   def get_port_profile(self):
00244     self._rtcout.RTC_TRACE("get_port_profile()")
00245 
00246     self.updateConnectors()
00247 
00248     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00249 
00250     prof = RTC.PortProfile(self._profile.name,
00251                            self._profile.interfaces,
00252                            self._profile.port_ref,
00253                            self._profile.connector_profiles,
00254                            self._profile.owner,
00255                            self._profile.properties)
00256 
00257     return prof
00258 
00259 
00260   ##
00261   # @if jp
00262   #
00263   # @brief PortProfile を取得する。
00264   #
00265   # この関数は、オブジェクト内部に保持されている PortProfile の
00266   # const 参照を返す const 関数である。
00267   # 
00268   # @post この関数を呼び出すことにより内部状態が変更されることはない。
00269   #
00270   # @return PortProfile
00271   #
00272   # @else
00273   #
00274   # @brief Get the PortProfile of the Port
00275   #
00276   # This function is a const function that returns a const
00277   # reference of the PortProfile stored in this Port.
00278   #
00279   # @post This function never changes the state of the object.
00280   #
00281   # @return PortProfile
00282   #
00283   # @endif
00284   # PortProfile& getPortProfile() const;
00285   def getPortProfile(self):
00286     self._rtcout.RTC_TRACE("getPortProfile()")
00287     return self._profile
00288 
00289 
00290   ##
00291   # @if jp
00292   #
00293   # @brief [CORBA interface] ConnectorProfileListを取得する
00294   #
00295   # Portが保持する ConnectorProfile の sequence を返す。
00296   # ConnectorProfile は Port 間の接続プロファイル情報を保持する構造体であり、
00297   # 接続時にPort間で情報交換を行い、関連するすべての Port で同一の値が
00298   # 保持される。
00299   # ConnectorProfile は以下のメンバーを保持している。
00300   #
00301   # - name         [string 型] このコネクタの名前。
00302   # - connector_id [string 型] ユニークなID
00303   # - ports        [Port sequnce] このコネクタに関連する Port のオブジェクト
00304   #                リファレンスのシーケンス。
00305   # - properties   [NVList 型] その他のプロパティ。
00306   #
00307   # @param self
00308   #
00309   # @return この Port が保持する ConnectorProfile
00310   #
00311   # @else
00312   #
00313   # @brief [CORBA interface] Get the ConnectorProfileList of the Port
00314   #
00315   # This operation returns a list of the ConnectorProfiles of the Port.
00316   # ConnectorProfile includes the connection information that describes 
00317   # relation between (among) Ports, and Ports exchange the ConnectionProfile
00318   # on connection process and hold the same information in each Port.
00319   # ConnectionProfile has the following members,
00320   #
00321   # - name         [string] The name of the connection.
00322   # - connector_id [string] Unique identifier.
00323   # - ports        [Port sequnce] The sequence of Port's object reference
00324   #                that are related the connection.
00325   # - properties   [NVList] The other properties.
00326   #
00327   # @return the ConnectorProfileList of the Port
00328   #
00329   # @endif
00330   # virtual ConnectorProfileList* get_connector_profiles()
00331   def get_connector_profiles(self):
00332     self._rtcout.RTC_TRACE("get_connector_profiles()")
00333 
00334     self.updateConnectors()
00335 
00336     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00337     return self._profile.connector_profiles
00338 
00339 
00340   ##
00341   # @if jp
00342   #
00343   # @brief [CORBA interface] ConnectorProfile を取得する
00344   #
00345   # connector_id で指定された ConnectorProfile を返す。
00346   # 指定した connector_id を持つ ConnectorProfile を保持していない場合は、
00347   # 空の ConnectorProfile を返す。
00348   #
00349   # @param self
00350   # @param connector_id ConnectorProfile の ID
00351   #
00352   # @return connector_id で指定された ConnectorProfile
00353   #
00354   # @else
00355   #
00356   # @brief [CORBA interface] Get the ConnectorProfile
00357   #
00358   # This operation returns the ConnectorProfiles specified connector_id.
00359   #
00360   # @param connector_id ID of the ConnectorProfile
00361   #
00362   # @return the ConnectorProfile identified by the connector_id
00363   #
00364   # @endif
00365   # ConnectorProfile* get_connector_profile(const char* connector_id)
00366   def get_connector_profile(self, connector_id):
00367     self._rtcout.RTC_TRACE("get_connector_profile(%s)", connector_id)
00368 
00369     self.updateConnectors()
00370 
00371     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00372     index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
00373                                             self.find_conn_id(connector_id))
00374     if index < 0:
00375       conn_prof = RTC.ConnectorProfile("","",[],[])
00376       return conn_prof
00377 
00378     conn_prof = RTC.ConnectorProfile(self._profile.connector_profiles[index].name,
00379                                      self._profile.connector_profiles[index].connector_id,
00380                                      self._profile.connector_profiles[index].ports,
00381                                      self._profile.connector_profiles[index].properties)
00382     return conn_prof
00383 
00384 
00385   ##
00386   # @if jp
00387   #
00388   # @brief [CORBA interface] Port の接続を行う
00389   #
00390   # 与えられた ConnectoionProfile の情報に基づき、Port間の接続を確立
00391   # する。この関数は主にアプリケーションプログラムやツールから呼び出
00392   # すことを前提としている。
00393   # 
00394   # @pre アプリケーションプログラムは、コンポーネント間の複数の
00395   # Port を接続するために、適切な値をセットした ConnectorProfile を
00396   # connect() の引数として与えて呼び出さなければならない。
00397   #
00398   # @pre connect() に与える ConnectorProfile のメンバーのうち、
00399   # name, ports, properties メンバーに対してデータをセットしなければ
00400   # ならない。connector_id には通常空文字を設定するか、適当なUUIDを
00401   # 文字列で設定する必要がある。
00402   #
00403   # @pre ConnectorProfile::name は接続につける名前で CORBA::string
00404   # 型に格納できる任意の文字列である必要がある。
00405   # 
00406   # @pre ConnectorProfile::connector_id はすべての接続に対して一意な
00407   # ID (通常はUUID) が格納される。UUIDの設定は connect() 関数内で行
00408   # われるので、呼び出し側は空文字を設定する。既存の接続と同じUUIDを
00409   # 設定し connect() を呼び出した場合には PRECONDITION_NOT_MET エラー
00410   # を返す。ただし、将来の拡張で既存の接続プロファイルを更新するため
00411   # に既存の UUID を設定して呼び出す使用法が用いられる可能性がある。
00412   #
00413   # @pre ConnectorProfile::ports は RTC::PortService のシーケンスで、
00414   # 接続を構成する通常2つ以上のポートのオブジェクト参照を代入する必
00415   # 要がある。例外として、ポートのオブジェクト参照を1つだけ格納して
00416   # connect()を呼び出すことで、ポートのインターフェース情報を取得し
00417   # たり、特殊なポート(CORBAのRTC::PortService以外の相手)に対して接
00418   # 続を行う場合もある。
00419   #
00420   # @pre ConnectorProfile::properties はポートに関連付けられたインター
00421   # フェースに対するプロパティを与えるために使用する。プロパティは、
00422   # string 型をキー、Any 型を値としてもつペアのシーケンスであり、値
00423   # には任意のCORBAデータ型を格納できるが、可能な限り string 型とし
00424   # て格納されることが推奨される。
00425   #
00426   # @pre 以上 connect() 呼び出し時に設定する ConnectorProfile のメン
00427   # バをまとめると以下のようになる。
00428   #
00429   # - ConnectorProfile::name: 任意の接続名
00430   # - ConnectorProfile::connector_id: 空文字
00431   # - ConnectorProfile::ports: 1つ以上のポート
00432   # - ConnectorProfile::properties: インターフェースに対するプロパティ
00433   #
00434   # @post connect() 関数は、ConnectorProfile::portsに格納されたポー
00435   # トシーケンスの先頭のポートに対して notify_connect() を呼ぶ。
00436   #
00437   # @post notify_connect() は ConnectorProfile::ports に格納されたポー
00438   # ト順に notify_connect() をカスケード呼び出しする。このカスケード
00439   # 呼び出しは、途中のnotify_connect() でエラーが出てもポートのオブ
00440   # ジェクト参照が有効である限り、必ずすべてのポートに対して行われる
00441   # ことが保証される。有効でないオブジェクト参照がシーケンス中に存在
00442   # する場合、そのポートをスキップして、次のポートに対して
00443   # notify_connect() を呼び出す。
00444   #
00445   # @post connect() 関数は、notify_connect()の戻り値がRTC_OKであれば、
00446   # RTC_OK を返す。この時点で接続は完了する。RTC_OK以外
00447   # の場合は、この接続IDに対してdisconnect()を呼び出し接続を解除し、
00448   # notify_connect() が返したエラーリターンコードをそのまま返す。
00449   # 
00450   # @post connect() の引数として渡した ConnectorProfile には、
00451   # ConnectorProfile::connector_id および、途中のポートが
00452   # publishInterfaces() で公開したポートインターフェースの各種情報が
00453   # 格納されている。connect() および途中の notify_connect() が
00454   # ConnectorProfile::{name, ports} を変更することはない。
00455   #  
00456   # @param connector_profile ConnectorProfile
00457   # @return ReturnCode_t 型のリターンコード
00458   #
00459   # @else
00460   #
00461   # @brief [CORBA interface] Connect the Port
00462   #
00463   # This operation establishes connection according to the given
00464   # ConnectionProfile inforamtion. This function is premised on
00465   # calling from mainly application program or tools.
00466   #
00467   # @pre To establish the connection among Ports of RT-Components,
00468   # application programs must call this operation giving
00469   # ConnectorProfile with valid values as an argument.
00470   #
00471   # @pre Out of ConnectorProfile member variables, "name", "ports"
00472   # and "properties" members shall be set valid
00473   # data. "connector_id" shall be set as empty string value or
00474   # valid string UUID value.
00475   #
00476   # @pre ConnectorProfile::name that is connection identifier shall
00477   # be any valid CORBA::string.
00478   # 
00479   #
00480   # @pre ConnectorProfile::connector_id shall be set unique
00481   # identifier (usually UUID is used) for all connections. Since
00482   # UUID string value is usually set in the connect() function,
00483   # caller should just set empty string. If the connect() is called
00484   # with the same UUID as existing connection, this function
00485   # returns PRECONDITION_NOT_MET error. However, in order to update
00486   # the existing connection profile, the "connect()" operation with
00487   # existing connector ID might be used as valid method by future
00488   # extension
00489   #
00490   # @pre ConnectorProfile::ports, which is sequence of
00491   # RTC::PortService references, shall store usually two or more
00492   # ports' references. As exceptions, the "connect()" operation
00493   # might be called with only one reference in ConnectorProfile, in
00494   # case of just getting interfaces information from the port, or
00495   # connecting a special port (i.e. the peer port except
00496   # RTC::PortService on CORBA).
00497   #
00498   # @pre ConnectorProfile::properties might be used to give certain
00499   # properties to the service interfaces associated with the port.
00500   # The properties is a sequence variable with a pair of key string
00501   # and Any type value. Although the A variable can store any type
00502   # of values, it is not recommended except string.
00503   #
00504   # @pre The following is the summary of the ConnectorProfile
00505   # member to be set when this operation is called.
00506   #
00507   # - ConnectorProfile::name: The any name of connection
00508   # - ConnectorProfile::connector_id: Empty string
00509   # - ConnectorProfile::ports: One or more port references
00510   # - ConnectorProfile::properties: Properties for the interfaces
00511   #
00512   # @post connect() operation will call the first port in the
00513   # sequence of the ConnectorProfile.
00514   #
00515   # @post "noify_connect()"s perform cascaded call to the ports
00516   # stored in the ConnectorProfile::ports by order. Even if errors
00517   # are raised by intermediate notify_connect() operation, as long
00518   # as ports' object references are valid, it is guaranteed that
00519   # this cascaded call is completed in all the ports.  If invalid
00520   # or dead ports exist in the port's sequence, the ports are
00521   # skipped and notify_connect() is called for the next valid port.
00522   #
00523   # @post connect() function returns RTC_OK if all the
00524   # notify_connect() return RTC_OK. At this time the connection is
00525   # completed.  If notify_connect()s return except RTC_OK,
00526   # connect() calls disconnect() operation with the connector_id to
00527   # destruct the connection, and then it returns error code from
00528   # notify_connect().
00529   #
00530   # @post The ConnectorProfile argument of the connect() operation
00531   # returns ConnectorProfile::connector_id and various information
00532   # about service interfaces that is published by
00533   # publishInterfaces() in the halfway ports. The connect() and
00534   # halfway notify_connect() functions never change
00535   # ConnectorProfile::{name, ports}.
00536   #
00537   # @param connector_profile The ConnectorProfile.
00538   # @return ReturnCode_t The return code of ReturnCode_t type.
00539   #
00540   # @endif
00541   #
00542   # virtual ReturnCode_t connect(ConnectorProfile& connector_profile)
00543   def connect(self, connector_profile):
00544     self._rtcout.RTC_TRACE("connect()")
00545     if self.isEmptyId(connector_profile):
00546       guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00547       self.setUUID(connector_profile)
00548       assert(not self.isExistingConnId(connector_profile.connector_id))
00549       del guard
00550     else:
00551       guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00552       if self.isExistingConnId(connector_profile.connector_id):
00553         self._rtcout.RTC_ERROR("Connection already exists.")
00554         return (RTC.PRECONDITION_NOT_MET,connector_profile)
00555       del guard
00556 
00557     try:
00558       retval,connector_profile = connector_profile.ports[0].notify_connect(connector_profile)
00559       if retval != RTC.RTC_OK:
00560         self._rtcout.RTC_ERROR("Connection failed. cleanup.")
00561         self.disconnect(connector_profile.connector_id)
00562     
00563       return (retval, connector_profile)
00564       #return connector_profile.ports[0].notify_connect(connector_profile)
00565     except:
00566       self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
00567       return (RTC.BAD_PARAMETER, connector_profile)
00568 
00569     return (RTC.RTC_ERROR, connector_profile)
00570 
00571 
00572   ##
00573   # @if jp
00574   #
00575   # @brief [CORBA interface] Port の接続通知を行う
00576   #
00577   # このオペレーションは、Port間の接続が行われる際に、Port間で内部的
00578   # に呼ばれるオペレーションであって、通常アプリケーションプログラム
00579   # や、Port以外のRTC関連オブジェクト等から呼び出されることは想定さ
00580   # れていない。
00581   #
00582   # notify_connect() 自体はテンプレートメソッドパターンとして、サブ
00583   # クラスで実装されることが前提の publishInterfaces(),
00584   # subscribeInterfaces() の2つの関数を内部で呼び出す。処理の手順は
00585   # 以下の通りである。
00586   #
00587   # - publishInterfaces(): インターフェース情報の公開
00588   # - connectNext(): 次の Port の notify_connect() の呼び出し
00589   # - subscribeInterfaces(): インターフェース情報の取得
00590   # - 接続情報の保存
00591   #
00592   # notify_connect() は ConnectorProfile::ports に格納されている
00593   # Port の順序に従って、カスケード状に呼び出しを行うことにより、イ
00594   # ンターフェース情報の公開と取得を関連すすべてのポートに対して行う。
00595   # このカスケード呼び出しは途中で中断されることはなく、必ず
00596   # ConnectorProfile::ports に格納されている全ポートに対して行われる。
00597   #
00598   # @pre notify_connect() は ConnectorProfile::ports 内に格納されて
00599   # いる Port 参照リストのうち、当該 Port 自身の参照の次に格納されて
00600   # いる Port に対して notify_connect() を呼び出す。したがって
00601   # ConnectorProfile::ports には当該 Port の参照が格納されている必要
00602   # がある。もし、自身の参照が格納されていない場合、その他の処理によ
00603   # りエラーが上書きされなければ、BAD_PARAMETER エラーが返される。
00604   #
00605   # @pre 呼び出し時に ConnectorProfile::connector_id には一意なIDと
00606   # して UUID が保持されている必要がある。通常 connector_id は
00607   # connect() 関数により与えられ、空文字の場合は動作は未定義である。
00608   #
00609   # @post ConnectorProfile::name, ConnectorProfile::connector_id,
00610   # ConnectorProfile::ports は notify_connect() の呼び出しにより
00611   # 書き換えられることはなく不変である。
00612   #
00613   # @post ConnectorProfile::properties は notify_connect() の内部で、
00614   # 当該 Port が持つサービスインターフェースに関する情報を他の Port
00615   # に伝えるために、プロパティ情報が書き込まれる。
00616   #
00617   # @post なお、ConnectorProfile::ports のリストの最初 Port の
00618   # notify_connet() が終了した時点では、すべての関連する Port の
00619   # notify_connect() の呼び出しが完了する。publishInterfaces(),
00620   # connectNext(), subscribeInterfaces() および接続情報の保存のいず
00621   # れかの段階でエラーが発生した場合でも、エラーコードは内部的に保持
00622   # されており、最初に生じたエラーのエラーコードが返される。
00623   #
00624   # @param connector_profile ConnectorProfile
00625   # @return ReturnCode_t 型のリターンコード
00626   #
00627   # @else
00628   #
00629   # @brief [CORBA interface] Notify the Ports connection
00630   #
00631   # This operation is usually called from other ports' connect() or
00632   # notify_connect() operations when connection between ports is
00633   # established.  This function is not premised on calling from
00634   # other functions or application programs.
00635   #
00636   # According to the template method pattern, the notify_connect()
00637   # calls "publishInterfaces()" and "subsctiveInterfaces()"
00638   # functions, which are premised on implementing in the
00639   # subclasses. The processing sequence is as follows.
00640   #
00641   # - publishInterfaces(): Publishing interface information
00642   # - connectNext(): Calling notify_connect() of the next port
00643   # - subscribeInterfaces(): Subscribing interface information
00644   # - Storing connection profile
00645   #
00646   # According to the order of port's references stored in the
00647   # ConnectorProfile::ports, publishing interface information to
00648   # all the ports and subscription interface information from all
00649   # the ports is performed by "notify_connect()"s.  This cascaded
00650   # call never aborts in the halfway operations, and calling
00651   # sequence shall be completed for all the ports.
00652   #
00653   # @pre notify_connect() calls notify_connect() for the port's
00654   # reference that is stored in next of this port's reference in
00655   # the sequence of the ConnectorProfile::ports. Therefore the
00656   # reference of this port shall be stored in the
00657   # ConnectorProfile::ports. If this port's reference is not stored
00658   # in the sequence, BAD_PARAMETER error will be returned, except
00659   # the return code is overwritten by other operations.
00660   #
00661   # @pre UUID shall be set to ConnectorProfile::connector_id as a
00662   # unique identifier when this operation is called.  Usually,
00663   # connector_id is given by a connect() function and, the behavior
00664   # is undefined in the case of a null character.
00665   #
00666   # @post ConnectorProfile::name, ConnectorProfile::connector_id,
00667   # ConnectorProfile::ports are invariant, and they are never
00668   # rewritten by notify_connect() operations.
00669   #
00670   # @post In order to transfer interface information to other
00671   # ports, interface property information is stored into the
00672   # ConnectorProfile::properties.
00673   #
00674   # @post At the end of notify_connect() operation for the first
00675   # port stored in the ConnectorProfile::ports sequence, the
00676   # related ports' notify_connect() invocations complete. Even if
00677   # errors are raised at the halfway of publishInterfaces(),
00678   # connectNext(), subscribeInterfaces() and storing process of
00679   # ConnectorProfile, error codes are saved and the first error is
00680   # returned.
00681   #
00682   # @param connector_profile The ConnectorProfile.
00683   # @return ReturnCode_t The return code of ReturnCode_t type.
00684   #
00685   # @endif
00686   #
00687   # virtual ReturnCode_t notify_connect(ConnectorProfile& connector_profile)
00688   def notify_connect(self, connector_profile):
00689     self._rtcout.RTC_TRACE("notify_connect()")
00690 
00691     guard_connection = OpenRTM_aist.ScopedLock(self._connection_mutex)
00692 
00693     # publish owned interface information to the ConnectorProfile
00694     retval = [RTC.RTC_OK for i in range(3)]
00695 
00696     self.onNotifyConnect(self.getName(),connector_profile)
00697     retval[0] = self.publishInterfaces(connector_profile)
00698     if retval[0] != RTC.RTC_OK:
00699       self._rtcout.RTC_ERROR("publishInterfaces() in notify_connect() failed.")
00700 
00701     self.onPublishInterfaces(self.getName(), connector_profile, retval[0])
00702     if self._onPublishInterfaces:
00703       self._onPublishInterfaces(connector_profile)
00704 
00705     # call notify_connect() of the next Port
00706     retval[1], connector_profile = self.connectNext(connector_profile)
00707     if retval[1] != RTC.RTC_OK:
00708       self._rtcout.RTC_ERROR("connectNext() in notify_connect() failed.")
00709 
00710     self.onConnectNextport(self.getName(), connector_profile, retval[1])
00711     # subscribe interface from the ConnectorProfile's information
00712     if self._onSubscribeInterfaces:
00713       self._onSubscribeInterfaces(connector_profile)
00714 
00715     retval[2] = self.subscribeInterfaces(connector_profile)
00716     if retval[2] != RTC.RTC_OK:
00717       self._rtcout.RTC_ERROR("subscribeInterfaces() in notify_connect() failed.")
00718       #self.notify_disconnect(connector_profile.connector_id)
00719 
00720     self.onSubscribeInterfaces(self.getName(), connector_profile, retval[2])
00721 
00722     self._rtcout.RTC_PARANOID("%d connectors are existing",
00723                               len(self._profile.connector_profiles))
00724 
00725     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00726     # update ConnectorProfile
00727     index = self.findConnProfileIndex(connector_profile.connector_id)
00728     if index < 0:
00729       OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.connector_profiles,
00730                                            connector_profile)
00731       self._rtcout.RTC_PARANOID("New connector_id. Push backed.")
00732 
00733     else:
00734       self._profile.connector_profiles[index] = connector_profile
00735       self._rtcout.RTC_PARANOID("Existing connector_id. Updated.")
00736 
00737     for ret in retval:
00738       if ret != RTC.RTC_OK:
00739         self.onConnected(self.getName(), connector_profile, ret)
00740         return (ret, connector_profile)
00741 
00742     # connection established without errors
00743     if self._onConnected:
00744       self._onConnected(connector_profile)
00745     self.onConnected(self.getName(), connector_profile, RTC.RTC_OK)
00746     return (RTC.RTC_OK, connector_profile)
00747 
00748 
00749   ##
00750   # @if jp
00751   #
00752   # @brief [CORBA interface] Port の接続を解除する
00753   #
00754   # このオペレーションは与えられた connector_id に対応する接続を解除
00755   # する。connector_id は通常、システム全体において一意な UUID の文
00756   # 字列であり、事前に connect()/notify_connect() の呼び出しにより確
00757   # 立された接続プロファイル ConnectorProfile::connector_id に対応す
00758   # る。
00759   #
00760   # @pre connector_id は Port が保持する ConnectorProfile の少なくと
00761   # も一つの ID に一致する文字列でなければならない。当該 Port が持つ
00762   # ConnectorProfile のリスト内に connector_id と同一の ID を持つ
00763   # ConnectorProfile が存在しなければこの関数は BAD_PARAMETER エラー
00764   # を返す。
00765   #
00766   # @pre connector_id と同じ ID を持つ ConnectorProfile::ports には
00767   # 有効な Port の参照が含まれていなければならない。
00768   #
00769   # @post disconnect() 関数は、ConnectorProfile::ports の Port の参
00770   # 照リストの先頭に対して、notify_disconnect() を呼び出す。参照が無
00771   # 効であるなど、notify_disconnect() の呼び出しに失敗した場合には、
00772   # 参照リストの先頭から順番に成功するまで notify_disconnect() の呼
00773   # び出しを試す。notify_disconnect() の呼び出しに一つでも成功すれば、
00774   # notify_disconnect() の返却値をそのまま返し、一つも成功しなかった
00775   # 場合には RTC_ERROR エラーを返す。
00776   # 
00777   # @param connector_id ConnectorProfile の ID
00778   # @return ReturnCode_t 型のリターンコード
00779   #
00780   # @else
00781   #
00782   # @brief [CORBA interface] Disconnect the Port
00783   #
00784   # This operation destroys connection between this port and the
00785   # peer port according to given connector_id. Usually connector_id
00786   # should be a UUID string that is unique in the system.  And the
00787   # connection, which is established by connect()/notify_connect()
00788   # functions, is identified by the ConnectorProfile::connector_id.
00789   #
00790   # @pre connector_id shall be a character string which is same
00791   # with ID of at least one of the ConnectorProfiles stored in this
00792   # port. If ConnectorProfile that has same ID with the given
00793   # connector_id does not exist in the list of ConnectorProfile,
00794   # this operation returns BAD_PARAMTER error.
00795   #
00796   # @pre ConnectorProfile::ports that is same ID with given
00797   # connector_id shall store the valid ports' references.
00798   #
00799   # @post disconnect() function invokes the notify_disconnect() for
00800   # the port that is stored in the first of the
00801   # ConnectorProfile::ports. If notify_disconnect() call fails for
00802   # the first port, It tries on calling "notify_disconnect()" in
00803   # order for ports stored in ConnectorProfile::ports until the
00804   # operation call is succeeded. If notify_disconnect() succeeded
00805   # for at least one port, it returns return code from
00806   # notify_disconnect(). If none of notify_connect() call
00807   # succeeded, it returns RTC_ERROR error.
00808   #
00809   # @param connector_id The ID of the ConnectorProfile.
00810   # @return ReturnCode_t The return code of ReturnCode_t type.
00811   #
00812   # @endif
00813   #
00814   # virtual ReturnCode_t disconnect(const char* connector_id)
00815   def disconnect(self, connector_id):
00816     self._rtcout.RTC_TRACE("disconnect(%s)", connector_id)
00817 
00818     index = self.findConnProfileIndex(connector_id)
00819 
00820     if index < 0:
00821       self._rtcout.RTC_ERROR("Invalid connector id: %s", connector_id)
00822       return RTC.BAD_PARAMETER
00823 
00824     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00825     if index < len(self._profile.connector_profiles):
00826       prof = self._profile.connector_profiles[index]
00827     del guard
00828     
00829     if len(prof.ports) < 1:
00830       self._rtcout.RTC_FATAL("ConnectorProfile has empty port list.")
00831       return RTC.PRECONDITION_NOT_MET
00832 
00833     for i in range(len(prof.ports)):
00834       p = prof.ports[i]
00835       try:
00836         return p.notify_disconnect(connector_id)
00837       except:
00838         self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
00839         continue
00840 
00841     self._rtcout.RTC_ERROR("notify_disconnect() for all ports failed.")
00842     return RTC.RTC_ERROR
00843 
00844 
00845   ##
00846   # @if jp
00847   #
00848   # @brief [CORBA interface] Port の接続解除通知を行う
00849   #
00850   # このオペレーションは、Port間の接続解除が行われる際に、Port間で内
00851   # 部的に呼ばれるオペレーションであり、通常アプリケーションプログラ
00852   # ムや、 Port 以外の RTC 関連オブジェクト等から呼び出されることは
00853   # 想定されていない。
00854   #
00855   # notify_disconnect() 自体はテンプレートメソッドパターンとして、サ
00856   # ブクラスで実装されることが前提の unsubscribeInterfaces() 関数を
00857   # 内部で呼び出す。処理の手順は以下の通りである。
00858   #
00859   # - ConnectorProfile の検索
00860   # - 次の Port の notify_disconnect() 呼び出し
00861   # - unsubscribeInterfaces()
00862   # - ConnectorProfile の削除
00863   #
00864   # notify_disconnect() は ConnectorProfile::ports に格納されている
00865   # Port の順序に従って、カスケード状に呼び出しを行うことにより、接
00866   # 続の解除をすべての Port に通知する。
00867   #
00868   # @pre Port は与えられた connector_id に対応する ConnectorProfile
00869   # を保持していなければならない。
00870   #
00871   # @post connector_id に対応する ConnectorProfile が見つからない場
00872   # 合はBAD_PARAMETER エラーを返す。
00873   #
00874   # @post カスケード呼び出しを行う際には ConnectorProfile::ports に
00875   # 保持されている Port の参照リストのうち、自身の参照の次の参照に対
00876   # して notify_disconnect() を呼び出すが、その呼び出しで例外が発生
00877   # した場合には、呼び出しをスキップしリストの次の参照に対して
00878   # notify_disconnect() を呼び出す。一つも呼び出しに成功しない場合、
00879   # RTC_ERROR エラーコードを返す。
00880   #
00881   # @post なお、ConnectorProfile::ports のリストの最初 Port の
00882   # notify_disconnet() が終了した時点では、すべての関連する Port の
00883   # notify_disconnect() の呼び出しが完了する。
00884   # 
00885   # @param connector_id ConnectorProfile の ID
00886   # @return ReturnCode_t 型のリターンコード
00887   #
00888   # @else
00889   #
00890   # @brief [CORBA interface] Notify the Ports disconnection
00891   #
00892   # This operation is invoked between Ports internally when the
00893   # connection is destroied. Generally it is not premised on
00894   # calling from application programs or RTC objects except Port
00895   # object.
00896   #
00897   # According to the template method pattern, the
00898   # notify_disconnect() calls unsubsctiveInterfaces() function,
00899   # which are premised on implementing in the subclasses. The
00900   # processing sequence is as follows.
00901   #
00902   # - Searching ConnectorProfile
00903   # - Calling notify_disconnect() for the next port
00904   # - Unsubscribing interfaces
00905   # - Deleting ConnectorProfile
00906   #
00907   # notify_disconnect() notifies disconnection to all the ports by
00908   # cascaded call to the stored ports in the
00909   # ConnectorProfile::ports in order.
00910   #
00911   # @pre The port shall store the ConnectorProfile having same id
00912   # with connector_id.
00913   #
00914   # @post If ConnectorProfile of same ID with connector_id does not
00915   # exist, it returns BAD_PARAMETER error.
00916   #
00917   # @post For the cascaded call, this operation calls
00918   # noify_disconnect() for the port that is stored in the next of
00919   # this port in the ConnectorProfile::ports.  If the operation
00920   # call raises exception for some failure, it tries to call
00921   # notify_disconnect() and skips until the operation succeeded.
00922   # If none of operation call succeeded, it returns RTC_ERROR.
00923   #
00924   # @post At the end of notify_disconnect() operation for the first
00925   # port stored in the ConnectorProfile::ports sequence, the
00926   # related ports' notify_disconnect() invocations complete.
00927   #
00928   # @param connector_id The ID of the ConnectorProfile.
00929   # @return ReturnCode_t The return code of ReturnCode_t type.
00930   #
00931   # @endif
00932   #
00933   # virtual ReturnCode_t notify_disconnect(const char* connector_id)
00934   def notify_disconnect(self, connector_id):
00935     self._rtcout.RTC_TRACE("notify_disconnect(%s)", connector_id)
00936 
00937     guard_connection = OpenRTM_aist.ScopedLock(self._connection_mutex)
00938     # The Port of which the reference is stored in the beginning of
00939     # connectorProfile's PortServiceList is master Port.
00940     # The master Port has the responsibility of disconnecting all Ports.
00941     # The slave Ports have only responsibility of deleting its own
00942     # ConnectorProfile.
00943 
00944     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00945 
00946     index = self.findConnProfileIndex(connector_id)
00947 
00948     if index < 0:
00949       self._rtcout.RTC_ERROR("Invalid connector id: %s", connector_id)
00950       return RTC.BAD_PARAMETER
00951 
00952     prof = RTC.ConnectorProfile(self._profile.connector_profiles[index].name,
00953                                 self._profile.connector_profiles[index].connector_id,
00954                                 self._profile.connector_profiles[index].ports,
00955                                 self._profile.connector_profiles[index].properties)
00956     self.onNotifyDisconnect(self.getName(), prof)
00957 
00958     retval = self.disconnectNext(prof)
00959     self.onDisconnectNextport(self.getName(), prof, retval)
00960 
00961     if self._onUnsubscribeInterfaces:
00962       self._onUnsubscribeInterfaces(prof)
00963     self.onUnsubscribeInterfaces(self.getName(), prof)
00964     self.unsubscribeInterfaces(prof)
00965 
00966     if self._onDisconnected:
00967       self._onDisconnected(prof)
00968 
00969     OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.connector_profiles, index)
00970     
00971     self.onDisconnected(self.getName(), prof, retval)
00972     return retval
00973 
00974 
00975   ##
00976   # @if jp
00977   #
00978   # @brief [CORBA interface] Port の全接続を解除する
00979   #
00980   # このオペレーションはこの Port に関連した全ての接続を解除する。
00981   #
00982   # @param self
00983   #
00984   # @return ReturnCode_t 型のリターンコード
00985   #
00986   # @else
00987   #
00988   # @brief [CORBA interface] Connect the Port
00989   #
00990   # This operation destroys all connection channels owned by the Port.
00991   #
00992   # @return ReturnCode_t The return code of this operation.
00993   #
00994   # @endif
00995   # virtual ReturnCode_t disconnect_all()
00996   def disconnect_all(self):
00997     self._rtcout.RTC_TRACE("disconnect_all()")
00998     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
00999     plist = copy.deepcopy(self._profile.connector_profiles)
01000     del guard
01001     
01002     retcode = RTC.RTC_OK
01003     len_ = len(plist)
01004     self._rtcout.RTC_DEBUG("disconnecting %d connections.", len_)
01005 
01006     # disconnect all connections
01007     # Call disconnect() for each ConnectorProfile.
01008     for i in range(len_):
01009       tmpret = self.disconnect(plist[i].connector_id)
01010       if tmpret != RTC.RTC_OK:
01011         retcode = tmpret
01012 
01013     return retcode
01014 
01015 
01016   #============================================================
01017   # Local operations
01018   #============================================================
01019 
01020   ##
01021   # @if jp
01022   # @brief Port の名前を設定する
01023   #
01024   # Port の名前を設定する。この名前は Port が保持する PortProfile.name
01025   # に反映される。
01026   #
01027   # @param self
01028   # @param name Port の名前
01029   #
01030   # @else
01031   # @brief Set the name of this Port
01032   #
01033   # This operation sets the name of this Port. The given Port's name is
01034   # applied to Port's PortProfile.name.
01035   #
01036   # @param name The name of this Port.
01037   #
01038   # @endif
01039   # void setName(const char* name);
01040   def setName(self, name):
01041     self._rtcout.RTC_TRACE("setName(%s)", name)
01042     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
01043     self._profile.name = name
01044     return
01045 
01046   ##
01047   # @if jp
01048   # @brief Port の名前を取得する
01049   # @else
01050   # @brief Get the name of this Port
01051   # @return The name of this Port.
01052   # @endif
01053   #
01054   # const char* PortBase::getName() const
01055   def getName(self):
01056     self._rtcout.RTC_TRACE("getName() = %s", self._profile.name)
01057     return self._profile.name
01058 
01059 
01060   ##
01061   # @if jp
01062   # @brief PortProfileを取得する
01063   #
01064   # Portが保持する PortProfile の const 参照を返す。
01065   #
01066   # @param self
01067   #
01068   # @return この Port の PortProfile
01069   #
01070   # @else
01071   # @brief Get the PortProfile of the Port
01072   #
01073   # This operation returns const reference of the PortProfile.
01074   #
01075   # @return the PortProfile of the Port
01076   #
01077   # @endif
01078   # const PortProfile& getProfile() const;
01079   def getProfile(self):
01080     self._rtcout.RTC_TRACE("getProfile()")
01081     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
01082     return self._profile
01083 
01084 
01085   ##
01086   # @if jp
01087   #
01088   # @brief Port のオブジェクト参照を設定する
01089   #
01090   # このオペレーションは Port の PortProfile にこの Port 自身の
01091   # オブジェクト参照を設定する。
01092   #
01093   # @param self
01094   # @param port_ref この Port のオブジェクト参照
01095   #
01096   # @else
01097   #
01098   # @brief Set the object reference of this Port
01099   #
01100   # This operation sets the object reference itself
01101   # to the Port's PortProfile.
01102   #
01103   # @param The object reference of this Port.
01104   #
01105   # @endif
01106   # void setPortRef(PortService_ptr port_ref);
01107   def setPortRef(self, port_ref):
01108     self._rtcout.RTC_TRACE("setPortRef()")
01109     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
01110     self._profile.port_ref = port_ref
01111 
01112 
01113   ##
01114   # @if jp
01115   #
01116   # @brief Port のオブジェクト参照を取得する
01117   #
01118   # このオペレーションは Port の PortProfile が保持している
01119   # この Port 自身のオブジェクト参照を取得する。
01120   #
01121   # @param self
01122   #
01123   # @return この Port のオブジェクト参照
01124   #
01125   # @else
01126   #
01127   # @brief Get the object reference of this Port
01128   #
01129   # This operation returns the object reference
01130   # that is stored in the Port's PortProfile.
01131   #
01132   # @return The object reference of this Port.
01133   #
01134   # @endif
01135   # PortService_ptr getPortRef();
01136   def getPortRef(self):
01137     self._rtcout.RTC_TRACE("getPortRef()")
01138     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
01139     return self._profile.port_ref
01140 
01141 
01142   ##
01143   # @if jp
01144   #
01145   # @brief Port の owner の RTObject を指定する
01146   #
01147   # このオペレーションは Port の PortProfile.owner を設定する。
01148   #
01149   # @param self
01150   # @param owner この Port を所有する RTObject の参照
01151   #
01152   # @else
01153   #
01154   # @brief Set the owner RTObject of the Port
01155   #
01156   # This operation sets the owner RTObject of this Port.
01157   #
01158   # @param owner The owner RTObject's reference of this Port
01159   #
01160   # @endif
01161   # void setOwner(RTObject_ptr owner);
01162   def setOwner(self, owner):
01163     prof = owner.get_component_profile()
01164     self._ownerInstanceName = prof.instance_name
01165     self._rtcout.RTC_TRACE("setOwner(%s)", self._ownerInstanceName)
01166 
01167     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
01168     plist = self._profile.name.split(".")
01169     if not self._ownerInstanceName:
01170       self._rtcout.RTC_ERROR("Owner is not set.")
01171       self._rtcout.RTC_ERROR("addXXXPort() should be called in onInitialize().")
01172     portname = self._ownerInstanceName+"."+plist[-1]
01173 
01174     self._profile.owner = owner
01175     self._profile.name = portname
01176 
01177 
01178   #============================================================
01179   # callbacks
01180   #============================================================
01181 
01182   ##
01183   # @if jp
01184   #
01185   # @brief インターフェースを公開する際に呼ばれるコールバックをセットする
01186   #
01187   # このオペレーションは、このポートが接続時に、ポート自身が持つサー
01188   # ビスインターフェース情報を公開するタイミングで呼ばれるコールバッ
01189   # クファンクタをセットする。
01190   #
01191   # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
01192   # が必要なくなった時に解体するのは呼び出し側の責任である。
01193   #
01194   # このコールバックファンクタは、PortBaseクラスの仮想関数である
01195   # publishInterfaces() が呼ばれたあとに、同じ引数 ConnectorProfile と
01196   # ともに呼び出される。このコールバックを利用して、
01197   # publishInterfaces() が公開した ConnectorProfile を変更することが可
01198   # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
01199   # 変更には注意を要する。
01200   #
01201   # @param on_publish ConnectionCallback のサブクラスオブジェクトのポインタ
01202   #
01203   # @else
01204   #
01205   # @brief Setting callback called on publish interfaces
01206   #
01207   # This operation sets a functor that is called after publishing
01208   # interfaces process when connecting between ports.
01209   #
01210   # Since the ownership of the callback functor object is owned by
01211   # the caller, it has the responsibility of object destruction.
01212   # 
01213   # The callback functor is called after calling
01214   # publishInterfaces() that is virtual member function of the
01215   # PortBase class with an argument of ConnectorProfile type that
01216   # is same as the argument of publishInterfaces() function.
01217   # Although by using this functor, you can modify the ConnectorProfile
01218   # published by publishInterfaces() function, the modification
01219   # should be done carefully for fear of causing connection
01220   # inconsistency.
01221   #
01222   # @param on_publish a pointer to ConnectionCallback's subclasses
01223   #
01224   # @endif
01225   #
01226   # void setOnPublishInterfaces(ConnectionCallback* on_publish);
01227   def setOnPublishInterfaces(self, on_publish):
01228     self._onPublishInterfaces = on_publish
01229     return
01230 
01231 
01232   ##
01233   # @if jp
01234   #
01235   # @brief インターフェースを取得する際に呼ばれるコールバックをセットする
01236   #
01237   # このオペレーションは、このポートが接続時に、相手のポートが持つサー
01238   # ビスインターフェース情報を取得するタイミングで呼ばれるコールバッ
01239   # クファンクタをセットする。
01240   #
01241   # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
01242   # が必要なくなった時に解体するのは呼び出し側の責任である。
01243   #
01244   # このコールバックファンクタは、PortBaseクラスの仮想関数である
01245   # subscribeInterfaces() が呼ばれる前に、同じ引数 ConnectorProfile と
01246   # ともに呼び出される。このコールバックを利用して、
01247   # subscribeInterfaces() に与える ConnectorProfile を変更することが可
01248   # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
01249   # 変更には注意を要する。
01250   #
01251   # @param on_subscribe ConnectionCallback のサブクラスオブジェクトのポインタ
01252   #
01253   # @else
01254   #
01255   # @brief Setting callback called on publish interfaces
01256   #
01257   # This operation sets a functor that is called before subscribing
01258   # interfaces process when connecting between ports.
01259   #
01260   # Since the ownership of the callback functor object is owned by
01261   # the caller, it has the responsibility of object destruction.
01262   # 
01263   # The callback functor is called before calling
01264   # subscribeInterfaces() that is virtual member function of the
01265   # PortBase class with an argument of ConnectorProfile type that
01266   # is same as the argument of subscribeInterfaces() function.
01267   # Although by using this functor, you can modify ConnectorProfile
01268   # argument for subscribeInterfaces() function, the modification
01269   # should be done carefully for fear of causing connection
01270   # inconsistency.
01271   #
01272   # @param on_subscribe a pointer to ConnectionCallback's subclasses
01273   #
01274   # @endif
01275   #
01276   #void setOnSubscribeInterfaces(ConnectionCallback* on_subscribe);
01277   def setOnSubscribeInterfaces(self, on_subscribe):
01278     self._onSubscribeInterfaces = on_subscribe
01279     return
01280 
01281 
01282   ##
01283   # @if jp
01284   #
01285   # @brief 接続完了時に呼ばれるコールバックをセットする
01286   #
01287   # このオペレーションは、このポートが接続完了時に呼ばれる、コールバッ
01288   # クファンクタをセットする。
01289   #
01290   # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
01291   # が必要なくなった時に解体するのは呼び出し側の責任である。
01292   #
01293   # このコールバックファンクタは、ポートの接続実行関数である
01294   # notify_connect() の終了直前に、接続処理が正常終了する際に限って
01295   # 呼び出されるコールバックである。接続処理の過程でエラーが発生した
01296   # 場合には呼び出されない。
01297   # 
01298   # このコールバックファンクタは notify_connect() が out パラメータ
01299   # として返すのと同じ引数 ConnectorProfile とともに呼び出されるので、
01300   # この接続において公開されたすべてのインターフェース情報を得ること
01301   # ができる。このコールバックを利用して、notify_connect() が返す
01302   # ConnectorProfile を変更することが可能であるが、接続関係の不整合
01303   # を招かないよう、ConnectorProfile の変更には注意を要する。
01304   #
01305   # @param on_subscribe ConnectionCallback のサブクラスオブジェクトのポインタ
01306   #
01307   # @else
01308   #
01309   # @brief Setting callback called on connection established
01310   #
01311   # This operation sets a functor that is called when connection
01312   # between ports established.
01313   #
01314   # Since the ownership of the callback functor object is owned by
01315   # the caller, it has the responsibility of object destruction.
01316   # 
01317   # The callback functor is called only when notify_connect()
01318   # function successfully returns. In case of error, the functor
01319   # will not be called.
01320   #
01321   # Since this functor is called with ConnectorProfile argument
01322   # that is same as out-parameter of notify_connect() function, you
01323   # can get all the information of published interfaces of related
01324   # ports in the connection.  Although by using this functor, you
01325   # can modify ConnectorProfile argument for out-paramter of
01326   # notify_connect(), the modification should be done carefully for
01327   # fear of causing connection inconsistency.
01328   #
01329   # @param on_subscribe a pointer to ConnectionCallback's subclasses
01330   #
01331   # @endif
01332   #
01333   # void setOnConnected(ConnectionCallback* on_connected);
01334   def setOnConnected(self, on_connected):
01335     self._onConnected = on_connected
01336     return
01337 
01338 
01339   ##
01340   # @if jp
01341   #
01342   # @brief インターフェースを解放する際に呼ばれるコールバックをセットする
01343   #
01344   # このオペレーションは、このポートが接続時に、相手のポートが持つサー
01345   # ビスインターフェース情報を解放するタイミングで呼ばれるコールバッ
01346   # クファンクタをセットする。
01347   #
01348   # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
01349   # が必要なくなった時に解体するのは呼び出し側の責任である。
01350   #
01351   # このコールバックファンクタは、PortBaseクラスの仮想関数である
01352   # unsubscribeInterfaces() が呼ばれる前に、同じ引数 ConnectorProfile と
01353   # ともに呼び出される。このコールバックを利用して、
01354   # unsubscribeInterfaces() に与える ConnectorProfile を変更することが可
01355   # 能であるが、接続関係の不整合を招かないよう、ConnectorProfile の
01356   # 変更には注意を要する。
01357   #
01358   # @param on_unsubscribe ConnectionCallback のサブクラスオブジェク
01359   # トのポインタ
01360   #
01361   # @else
01362   #
01363   # @brief Setting callback called on unsubscribe interfaces
01364   #
01365   # This operation sets a functor that is called before unsubscribing
01366   # interfaces process when disconnecting between ports.
01367   #
01368   # Since the ownership of the callback functor object is owned by
01369   # the caller, it has the responsibility of object destruction.
01370   # 
01371   # The callback functor is called before calling
01372   # unsubscribeInterfaces() that is virtual member function of the
01373   # PortBase class with an argument of ConnectorProfile type that
01374   # is same as the argument of unsubscribeInterfaces() function.
01375   # Although by using this functor, you can modify ConnectorProfile
01376   # argument for unsubscribeInterfaces() function, the modification
01377   # should be done carefully for fear of causing connection
01378   # inconsistency.
01379   #
01380   # @param on_unsubscribe a pointer to ConnectionCallback's subclasses
01381   #
01382   # @endif
01383   #
01384   # void setOnUnsubscribeInterfaces(ConnectionCallback* on_subscribe);
01385   def setOnUnsubscribeInterfaces(self, on_subscribe):
01386     self._onUnsubscribeInterfaces = on_subscribe
01387     return
01388 
01389 
01390   ##
01391   # @if jp
01392   #
01393   # @brief 接続解除に呼ばれるコールバックをセットする
01394   #
01395   # このオペレーションは、このポートの接続解除時に呼ばれる、コールバッ
01396   # クファンクタをセットする。
01397   #
01398   # コールバックファンクタの所有権は、呼び出し側にあり、オブジェクト
01399   # が必要なくなった時に解体するのは呼び出し側の責任である。
01400   #
01401   # このコールバックファンクタは、ポートの接続解除実行関数である
01402   # notify_disconnect() の終了直前に、呼び出されるコールバックである。
01403   # 
01404   # このコールバックファンクタは接続に対応する ConnectorProfile とと
01405   # もに呼び出される。この ConnectorProfile はこのファンクタ呼出し後
01406   # に破棄されるので、変更がほかに影響を与えることはない。
01407   #
01408   # @param on_disconnected ConnectionCallback のサブクラスオブジェク
01409   # トのポインタ
01410   #
01411   # @else
01412   #
01413   # @brief Setting callback called on disconnected
01414   #
01415   # This operation sets a functor that is called when connection
01416   # between ports is destructed.
01417   #
01418   # Since the ownership of the callback functor object is owned by
01419   # the caller, it has the responsibility of object destruction.
01420   # 
01421   # The callback functor is called just before notify_disconnect()
01422   # that is disconnection execution function returns.
01423   #
01424   # This functor is called with argument of corresponding
01425   # ConnectorProfile.  Since this ConnectorProfile will be
01426   # destructed after calling this functor, modifications never
01427   # affect others.
01428   #
01429   # @param on_disconnected a pointer to ConnectionCallback's subclasses
01430   #
01431   # @endif
01432   #
01433   # void setOnDisconnected(ConnectionCallback* on_disconnected);
01434   def setOnDisconnected(self, on_disconnected):
01435     self._onDisconnected = on_disconnected
01436     return
01437 
01438   # void setOnConnectionLost(ConnectionCallback* on_connection_lost);
01439   def setOnConnectionLost(self, on_connection_lost):
01440     self._onConnectionLost = on_connection_lost
01441     return
01442 
01443 
01444   ##
01445   # @if jp
01446   # @brief PortConnectListeners のホルダをセットする
01447   #
01448   # ポートの接続に関するリスナ群を保持するホルダクラスへのポインタを
01449   # セットする。この関数は通常親のRTObjectから呼ばれ、RTObjectが持つ
01450   # ホルダクラスへのポインタがセットされる。
01451   #
01452   # @param portconnListeners PortConnectListeners オブジェクトのポインタ
01453   #
01454   # @else
01455   # @brief Setting PortConnectListener holder
01456   #
01457   # This operation sets a functor that is called when connection
01458   # of this port does lost. 
01459   #
01460   # @param on_connection_lost a pointer to ConnectionCallback's subclasses
01461   #
01462   # @endif
01463   #
01464   # void setPortConnectListenerHolder(PortConnectListeners* portconnListeners);
01465   def setPortConnectListenerHolder(self, portconnListeners):
01466     self._portconnListeners = portconnListeners
01467     return
01468 
01469 
01470   ##
01471   # @if jp
01472   #
01473   # @brief Interface 情報を公開する(サブクラス実装用)
01474   #
01475   # このオペレーションは、notify_connect() 処理シーケンスの始めにコール
01476   # される関数である。
01477   # notify_connect() では、
01478   #
01479   # - publishInterfaces()
01480   # - connectNext()
01481   # - subscribeInterfaces()
01482   # - updateConnectorProfile()
01483   #
01484   # の順に protected 関数がコールされ接続処理が行われる。
01485   # <br>
01486   # 具象 Port ではこのオペレーションをオーバーライドし、引数として
01487   # 与えられた ConnectorProfile に従い処理を行い、パラメータが不適切
01488   # であれば、RteurnCode_t 型のエラーコードを返す。
01489   # 通常 publishInterafaces() 内においては、この Port に属する
01490   # インターフェースに関する情報を ConnectorProfile に対して適切に設定し
01491   # 他の Port に通知しなければならない。
01492   # <br>
01493   # また、この関数がコールされる段階では、他の Port の Interface に関する
01494   # 情報はすべて含まれていないので、他の Port の Interface を取得する処理
01495   # は subscribeInterfaces() 内で行われるべきである。
01496   # <br>
01497   # このオペレーションは、新規の connector_id に対しては接続の生成、
01498   # 既存の connector_id に対しては更新が適切に行われる必要がある。<BR>
01499   # ※サブクラスでの実装参照用
01500   #
01501   # @param self
01502   # @param connector_profile 接続に関するプロファイル情報
01503   #
01504   # @return ReturnCode_t 型のリターンコード
01505   #
01506   # @else
01507   #
01508   # @brief Publish interface information
01509   #
01510   # This operation is pure virutal method that would be called at the
01511   # beginning of the notify_connect() process sequence.
01512   # In the notify_connect(), the following methods would be called in order.
01513   #
01514   # - publishInterfaces()
01515   # - connectNext()
01516   # - subscribeInterfaces()
01517   # - updateConnectorProfile() 
01518   #
01519   # In the concrete Port, this method should be overridden. This method
01520   # processes the given ConnectorProfile argument and if the given parameter
01521   # is invalid, it would return error code of ReturnCode_t.
01522   # Usually, publishInterfaces() method should set interfaces information
01523   # owned by this Port, and publish it to the other Ports.
01524   # <br>
01525   # When this method is called, other Ports' interfaces information may not
01526   # be completed. Therefore, the process to obtain other Port's interfaces
01527   # information should be done in the subscribeInterfaces() method.
01528   # <br>
01529   # This operation should create the new connection for the new
01530   # connector_id, and should update the connection for the existing
01531   # connection_id.
01532   #
01533   # @param connector_profile The connection profile information
01534   # @return The return code of ReturnCode_t type.
01535   #
01536   #@endif
01537   def publishInterfaces(self, connector_profile):
01538     pass
01539 
01540 
01541   ##
01542   # @if jp
01543   #
01544   # @brief 次の Port に対して notify_connect() をコールする
01545   #
01546   # ConnectorProfile の port_ref 内に格納されている Port のオブジェクト
01547   # リファレンスのシーケンスの中から、自身の Port の次の Port に対して
01548   # notify_connect() をコールする。
01549   #
01550   # @param self
01551   # @param connector_profile 接続に関するプロファイル情報
01552   #
01553   # @return ReturnCode_t 型のリターンコード
01554   #
01555   # @else
01556   #
01557   # @brief Call notify_connect() of the next Port
01558   #
01559   # This operation calls the notify_connect() of the next Port's 
01560   # that stored in ConnectorProfile's port_ref sequence.
01561   #
01562   # @param connector_profile The connection profile information
01563   #
01564   # @return The return code of ReturnCode_t type.
01565   #
01566   # @endif
01567   # virtual ReturnCode_t connectNext(ConnectorProfile& connector_profile);
01568   def connectNext(self, connector_profile):
01569     index = OpenRTM_aist.CORBA_SeqUtil.find(connector_profile.ports,
01570                                             self.find_port_ref(self._profile.port_ref))
01571     if index < 0:
01572       return (RTC.BAD_PARAMETER, connector_profile)
01573 
01574     index += 1
01575     if index < len(connector_profile.ports):
01576       p = connector_profile.ports[index]
01577       return p.notify_connect(connector_profile)
01578 
01579     return (RTC.RTC_OK, connector_profile)
01580 
01581 
01582   ##
01583   # @if jp
01584   #
01585   # @brief 次の Port に対して notify_disconnect() をコールする
01586   #
01587   # ConnectorProfile の port_ref 内に格納されている Port のオブジェクト
01588   # リファレンスのシーケンスの中から、自身の Port の次の Port に対して
01589   # notify_disconnect() をコールする。
01590   #
01591   # @param self
01592   # @param connector_profile 接続に関するプロファイル情報
01593   #
01594   # @return ReturnCode_t 型のリターンコード
01595   #
01596   # @else
01597   #
01598   # @brief Call notify_disconnect() of the next Port
01599   #
01600   # This operation calls the notify_disconnect() of the next Port's 
01601   # that stored in ConnectorProfile's port_ref sequence.
01602   #
01603   # @param connector_profile The connection profile information
01604   #
01605   # @return The return code of ReturnCode_t type.
01606   #
01607   # @endif
01608   # virtual ReturnCode_t disconnectNext(ConnectorProfile& connector_profile);
01609   def disconnectNext(self, connector_profile):
01610     index = OpenRTM_aist.CORBA_SeqUtil.find(connector_profile.ports,
01611                                             self.find_port_ref(self._profile.port_ref))
01612     if index < 0:
01613       return RTC.BAD_PARAMETER
01614 
01615     if index == (len(connector_profile.ports) - 1):
01616       return RTC.RTC_OK
01617 
01618     index += 1
01619 
01620     while index < len(connector_profile.ports):
01621       p = connector_profile.ports[index]
01622       index += 1
01623       try:
01624         return p.notify_disconnect(connector_profile.connector_id)
01625       except:
01626         self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
01627         continue
01628 
01629     return RTC.RTC_ERROR
01630 
01631 
01632   ##
01633   # @if jp
01634   #
01635   # @brief Interface 情報を取得する(サブクラス実装用)
01636   #
01637   # このオペレーションは、notify_connect() 処理シーケンスの中間にコール
01638   # される関数である。
01639   # notify_connect() では、
01640   #
01641   #  - publishInterfaces()
01642   #  - connectNext()
01643   #  - subscribeInterfaces()
01644   #  - updateConnectorProfile()
01645   #
01646   # の順に protected 関数がコールされ接続処理が行われる。
01647   # <br>
01648   # 具象 Port ではこのオペレーションをオーバーライドし、引数として
01649   # 与えられた ConnectorProfile に従い処理を行い、パラメータが不適切
01650   # であれば、RteurnCode_t 型のエラーコードを返す。
01651   # 引数 ConnectorProfile には他の Port の Interface に関する情報が
01652   # 全て含まれている。
01653   # 通常 subscribeInterafaces() 内においては、この Port が使用する
01654   # Interface に関する情報を取得し、要求側のインターフェースに対して
01655   # 情報を設定しなければならない。
01656   # <br>
01657   # このオペレーションは、新規の connector_id に対しては接続の生成、
01658   # 既存の connector_id に対しては更新が適切に行われる必要がある。<BR>
01659   # ※サブクラスでの実装参照用
01660   #
01661   # @param self
01662   # @param connector_profile 接続に関するプロファイル情報
01663   #
01664   # @return ReturnCode_t 型のリターンコード
01665   #
01666   # @else
01667   #
01668   # @brief Publish interface information
01669   #
01670   # This operation is pure virutal method that would be called at the
01671   # mid-flow of the notify_connect() process sequence.
01672   # In the notify_connect(), the following methods would be called in order.
01673   #
01674   #  - publishInterfaces()
01675   #  - connectNext()
01676   #  - subscribeInterfaces()
01677   #  - updateConnectorProfile()
01678   #
01679   # In the concrete Port, this method should be overridden. This method
01680   # processes the given ConnectorProfile argument and if the given parameter
01681   # is invalid, it would return error code of ReturnCode_t.
01682   # The given argument ConnectorProfile includes all the interfaces
01683   # information in it.
01684   # Usually, subscribeInterafaces() method obtains information of interfaces
01685   # from ConnectorProfile, and should set it to the interfaces that require
01686   # them.
01687   # <br>
01688   # This operation should create the new connection for the new
01689   # connector_id, and should update the connection for the existing
01690   # connection_id.
01691   #
01692   # @param connector_profile The connection profile information
01693   #
01694   # @return The return code of ReturnCode_t type.
01695   #
01696   #@endif
01697   def subscribeInterfaces(self, connector_profile):
01698     pass
01699 
01700 
01701   ##
01702   # @if jp
01703   #
01704   # @brief Interface の接続を解除する(サブクラス実装用)
01705   #
01706   # このオペレーションは、notify_disconnect() 処理シーケンスの終わりにコール
01707   # される関数である。
01708   # notify_disconnect() では、
01709   #  - disconnectNext()
01710   #  - unsubscribeInterfaces()
01711   #  - eraseConnectorProfile()
01712   # の順に protected 関数がコールされ接続解除処理が行われる。
01713   # <br>
01714   # 具象 Port ではこのオペレーションをオーバーライドし、引数として
01715   # 与えられた ConnectorProfile に従い接続解除処理を行う。<BR>
01716   # ※サブクラスでの実装参照用
01717   #
01718   # @param self
01719   # @param connector_profile 接続に関するプロファイル情報
01720   #
01721   # @else
01722   #
01723   # @brief Disconnect interface connection
01724   #
01725   # This operation is pure virutal method that would be called at the
01726   # end of the notify_disconnect() process sequence.
01727   # In the notify_disconnect(), the following methods would be called.
01728   #  - disconnectNext()
01729   #  - unsubscribeInterfaces()
01730   #  - eraseConnectorProfile() 
01731   # <br>
01732   # In the concrete Port, this method should be overridden. This method
01733   # processes the given ConnectorProfile argument and disconnect interface
01734   # connection.
01735   #
01736   # @param connector_profile The connection profile information
01737   #
01738   # @endif
01739   def unsubscribeInterfaces(self, connector_profile):
01740     pass
01741 
01742 
01743   ##
01744   # @if jp
01745   #
01746   # @brief 接続の最大数を設定する。
01747   #
01748   # @param limit_value 最大数
01749   #
01750   # @else
01751   #
01752   # @brief Set the maximum number of connections
01753   #
01754   #
01755   # @param limit_value The maximum number of connections
01756   #
01757   # @endif
01758   #
01759   # virtual void setConnectionLimit(int limit_value);
01760   def setConnectionLimit(self, limit_value):
01761     self._connectionLimit = limit_value
01762     return
01763     
01764 
01765   ##
01766   # @if jp
01767   # @brief Interface情報を公開する
01768   #
01769   # Interface情報を公開する。
01770   #
01771   #  dataport.dataflow_type
01772   #
01773   # @return ReturnCode_t 型のリターンコード
01774   #
01775   # @else
01776   # @brief Publish interface information
01777   #
01778   # Publish interface information.
01779   #
01780   #
01781   # @return The return code of ReturnCode_t type
01782   #
01783   # @endif
01784   #
01785   # virtual ReturnCode_t _publishInterfaces(void);
01786   def _publishInterfaces(self):
01787     if not (self._connectionLimit < 0) :
01788       if self._connectionLimit <= len(self._profile.connector_profiles):
01789         self._rtcout.RTC_PARANOID("Connected number has reached the limitation.")
01790         self._rtcout.RTC_PARANOID("Can connect the port up to %d ports.",
01791                                   self._connectionLimit)
01792         self._rtcout.RTC_PARANOID("%d connectors are existing",
01793                                   len(self._profile.connector_profiles))
01794         return RTC.RTC_ERROR
01795 
01796     return RTC.RTC_OK
01797 
01798 
01799   ##
01800   # @if jp
01801   #
01802   # @brief ConnectorProfile の connector_id フィールドが空かどうか判定
01803   #
01804   # 指定された ConnectorProfile の connector_id が空であるかどうかの判定を
01805   # 行う。
01806   #
01807   # @param self
01808   # @param connector_profile 判定対象コネクタプロファイル
01809   #
01810   # @return 引数で与えられた ConnectorProfile の connector_id が空であれば、
01811   #         true、そうでなければ false を返す。
01812   #
01813   # @else
01814   #
01815   # @brief Whether connector_id of ConnectorProfile is empty
01816   #
01817   # @return If the given ConnectorProfile's connector_id is empty string,
01818   #         it returns true.
01819   #
01820   # @endif
01821   # bool isEmptyId(const ConnectorProfile& connector_profile) const;
01822   def isEmptyId(self, connector_profile):
01823     return connector_profile.connector_id == ""
01824 
01825 
01826   ##
01827   # @if jp
01828   #
01829   # @brief UUIDを生成する
01830   #
01831   # このオペレーションは UUID を生成する。
01832   #
01833   # @param self
01834   #
01835   # @return uuid
01836   #
01837   # @else
01838   #
01839   # @brief Get the UUID
01840   #
01841   # This operation generates UUID.
01842   #
01843   # @return uuid
01844   #
01845   # @endif
01846   # const std::string getUUID() const;
01847   def getUUID(self):
01848     return str(OpenRTM_aist.uuid1())
01849 
01850 
01851   ##
01852   # @if jp
01853   #
01854   # @brief UUIDを生成し ConnectorProfile にセットする
01855   #
01856   # このオペレーションは UUID を生成し、ConnectorProfile にセットする。
01857   #
01858   # @param self
01859   # @param connector_profile connector_id をセットする ConnectorProfile
01860   #
01861   # @else
01862   #
01863   # @brief Create and set the UUID to the ConnectorProfile
01864   #
01865   # This operation generates and set UUID to the ConnectorProfile.
01866   #
01867   # @param connector_profile ConnectorProfile to be set connector_id
01868   #
01869   # @endif
01870   # void setUUID(ConnectorProfile& connector_profile) const;
01871   def setUUID(self, connector_profile):
01872     connector_profile.connector_id = self.getUUID()
01873     assert(connector_profile.connector_id != "")
01874 
01875 
01876   ##
01877   # @if jp
01878   #
01879   # @brief id が既存の ConnectorProfile のものかどうか判定する
01880   #
01881   # このオペレーションは与えられた ID が既存の ConnectorProfile のリスト中に
01882   # 存在するかどうか判定する。
01883   #
01884   # @param self
01885   # @param id_ 判定する connector_id
01886   #
01887   # @return id の存在判定結果
01888   #
01889   # @else
01890   #
01891   # @brief Whether the given id exists in stored ConnectorProfiles
01892   #
01893   # This operation returns boolean whether the given id exists in 
01894   # the Port's ConnectorProfiles.
01895   #
01896   # @param id connector_id to be find in Port's ConnectorProfiles
01897   #
01898   # @endif
01899   # bool isExistingConnId(const char* id);
01900   def isExistingConnId(self, id_):
01901     return OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
01902                                            self.find_conn_id(id_)) >= 0
01903 
01904 
01905   ##
01906   # @if jp
01907   #
01908   # @brief id を持つ ConnectorProfile を探す
01909   #
01910   # このオペレーションは与えられた ID を持つ ConnectorProfile を Port が
01911   # もつ ConnectorProfile のリスト中から探す。
01912   # もし、同一の id を持つ ConnectorProfile がなければ、空の ConnectorProfile
01913   # が返される。
01914   #
01915   # @param self
01916   # @param id_ 検索する connector_id
01917   #
01918   # @return connector_id を持つ ConnectorProfile
01919   #
01920   # @else
01921   #
01922   # @brief Find ConnectorProfile with id
01923   #
01924   # This operation returns ConnectorProfile with the given id from Port's
01925   # ConnectorProfiles' list.
01926   # If the ConnectorProfile with connector id that is identical with the
01927   # given id does not exist, empty ConnectorProfile is returned.
01928   #
01929   # @param id the connector_id to be searched in Port's ConnectorProfiles
01930   #
01931   # @return CoonectorProfile with connector_id
01932   #
01933   # @endif
01934   # ConnectorProfile findConnProfile(const char* id);
01935   def findConnProfile(self, id_):
01936     index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
01937                                             self.find_conn_id(id_))
01938     if index < 0 or index >= len(self._profile.connector_profiles):
01939       return RTC.ConnectorProfile("","",[],[])
01940 
01941     return self._profile.connector_profiles[index]
01942 
01943 
01944   ##
01945   # @if jp
01946   #
01947   # @brief id を持つ ConnectorProfile を探す
01948   #
01949   # このオペレーションは与えられた ID を持つ ConnectorProfile を Port が
01950   # もつ ConnectorProfile のリスト中から探しインデックスを返す。
01951   # もし、同一の id を持つ ConnectorProfile がなければ、-1 を返す。
01952   #
01953   # @param self
01954   # @param id_ 検索する connector_id
01955   #
01956   # @return Port の ConnectorProfile リストのインデックス
01957   #
01958   # @else
01959   #
01960   # @brief Find ConnectorProfile with id
01961   #
01962   # This operation returns ConnectorProfile with the given id from Port's
01963   # ConnectorProfiles' list.
01964   # If the ConnectorProfile with connector id that is identical with the
01965   # given id does not exist, empty ConnectorProfile is returned.
01966   #
01967   # @param id the connector_id to be searched in Port's ConnectorProfiles
01968   #
01969   # @return The index of ConnectorProfile of the Port
01970   #
01971   # @endif
01972   # CORBA::Long findConnProfileIndex(const char* id);
01973   def findConnProfileIndex(self, id_):
01974     return OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
01975                                            self.find_conn_id(id_))
01976 
01977 
01978   ##
01979   # @if jp
01980   #
01981   # @brief ConnectorProfile の追加もしくは更新
01982   #
01983   # このオペレーションは与えられた与えられた ConnectorProfile を
01984   # Port に追加もしくは更新保存する。
01985   # 与えられた ConnectorProfile の connector_id と同じ ID を持つ
01986   # ConnectorProfile がリストになければ、リストに追加し、
01987   # 同じ ID が存在すれば ConnectorProfile を上書き保存する。
01988   #
01989   # @param self
01990   # @param connector_profile 追加もしくは更新する ConnectorProfile
01991   #
01992   # @else
01993   #
01994   # @brief Append or update the ConnectorProfile list
01995   #
01996   # This operation appends or updates ConnectorProfile of the Port
01997   # by the given ConnectorProfile.
01998   # If the connector_id of the given ConnectorProfile does not exist
01999   # in the Port's ConnectorProfile list, the given ConnectorProfile would be
02000   # append to the list. If the same id exists, the list would be updated.
02001   #
02002   # @param connector_profile the ConnectorProfile to be appended or updated
02003   #
02004   # @endif
02005   # void updateConnectorProfile(const ConnectorProfile& connector_profile);
02006   def updateConnectorProfile(self, connector_profile):
02007     index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
02008                                             self.find_conn_id(connector_profile.connector_id))
02009 
02010     if index < 0:
02011       OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.connector_profiles,
02012                                            connector_profile)
02013     else:
02014       self._profile.connector_profiles[index] = connector_profile
02015 
02016 
02017   ##
02018   # @if jp
02019   #
02020   # @brief ConnectorProfile を削除する
02021   #
02022   # このオペレーションは Port の PortProfile が保持している
02023   # ConnectorProfileList のうち与えられた id を持つ ConnectorProfile
02024   # を削除する。
02025   #
02026   # @param self
02027   # @param id_ 削除する ConnectorProfile の id
02028   #
02029   # @return 正常に削除できた場合は true、
02030   #         指定した ConnectorProfile が見つからない場合は false を返す
02031   #
02032   # @else
02033   #
02034   # @brief Delete the ConnectorProfile
02035   #
02036   # This operation deletes a ConnectorProfile specified by id from
02037   # ConnectorProfileList owned by PortProfile of this Port.
02038   #
02039   # @param id The id of the ConnectorProfile to be deleted.
02040   #
02041   # @endif
02042   # bool eraseConnectorProfile(const char* id);
02043   def eraseConnectorProfile(self, id_):
02044     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
02045 
02046     index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.connector_profiles,
02047                                             self.find_conn_id(id_))
02048 
02049     if index < 0:
02050       return False
02051 
02052     OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.connector_profiles, index)
02053 
02054     return True
02055 
02056 
02057   ##
02058   # @if jp
02059   #
02060   # @brief PortInterfaceProfile に インターフェースを登録する
02061   #
02062   # このオペレーションは Port が持つ PortProfile の、PortInterfaceProfile
02063   # にインターフェースの情報を追加する。
02064   # この情報は、get_port_profile() 似よって得られる PortProfile のうち
02065   # PortInterfaceProfile の値を変更するのみであり、実際にインターフェースを
02066   # 提供したり要求したりする場合には、サブクラスで、 publishInterface() ,
02067   #  subscribeInterface() 等の関数を適切にオーバーライドしインターフェースの
02068   # 提供、要求処理を行わなければならない。
02069   #
02070   # インターフェース(のインスタンス)名は Port 内で一意でなければならない。
02071   # 同名のインターフェースがすでに登録されている場合、この関数は false を
02072   # 返す。
02073   #
02074   # @param self
02075   # @param instance_name インターフェースのインスタンスの名前
02076   # @param type_name インターフェースの型の名前
02077   # @param pol インターフェースの属性 (RTC::PROVIDED もしくは RTC:REQUIRED)
02078   #
02079   # @return インターフェース登録処理結果。
02080   #         同名のインターフェースが既に登録されていれば false を返す。
02081   #
02082   # @else
02083   #
02084   # @brief Append an interface to the PortInterfaceProfile
02085   #
02086   # This operation appends interface information to the PortInterfaceProfile
02087   # that is owned by the Port.
02088   # The given interfaces information only updates PortInterfaceProfile of
02089   # PortProfile that is obtained through get_port_profile().
02090   # In order to provide and require interfaces, proper functions (for
02091   # example publishInterface(), subscribeInterface() and so on) should be
02092   # overridden in subclasses, and these functions provide concrete interface
02093   # connection and disconnection functionality.
02094   #
02095   # The interface (instance) name have to be unique in the Port.
02096   # If the given interface name is identical with stored interface name,
02097   # this function returns false.
02098   #
02099   # @param name The instance name of the interface.
02100   # @param type_name The type name of the interface.
02101   # @param pol The interface's polarity (RTC::PROVIDED or RTC:REQUIRED)
02102   #
02103   # @return false would be returned if the same name is already registered.
02104   #
02105   # @endif
02106   # bool appendInterface(const char* name, const char* type_name,
02107   #                      PortInterfacePolarity pol);
02108   def appendInterface(self, instance_name, type_name, pol):
02109     index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.interfaces,
02110                                             self.find_interface(instance_name, pol))
02111 
02112     if index >= 0:
02113       return False
02114 
02115     # setup PortInterfaceProfile
02116     prof = RTC.PortInterfaceProfile(instance_name, type_name, pol)
02117     OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.interfaces, prof)
02118 
02119     return True
02120 
02121 
02122   ##
02123   # @if jp
02124   #
02125   # @brief PortInterfaceProfile からインターフェース登録を削除する
02126   #
02127   # このオペレーションは Port が持つ PortProfile の、PortInterfaceProfile
02128   # からインターフェースの情報を削除する。
02129   #
02130   # @param self
02131   # @param name インターフェースのインスタンスの名前
02132   # @param pol インターフェースの属性 (RTC::PROVIDED もしくは RTC:REQUIRED)
02133   #
02134   # @return インターフェース削除処理結果。
02135   #         インターフェースが登録されていなければ false を返す。
02136   #
02137   # @else
02138   #
02139   # @brief Delete an interface from the PortInterfaceProfile
02140   #
02141   # This operation deletes interface information from the
02142   # PortInterfaceProfile that is owned by the Port.
02143   #
02144   # @param name The instance name of the interface.
02145   # @param pol The interface's polarity (RTC::PROVIDED or RTC:REQUIRED)
02146   #
02147   # @return false would be returned if the given name is not registered.
02148   #
02149   # @endif
02150   # bool deleteInterface(const char* name, PortInterfacePolarity pol);
02151   def deleteInterface(self, name, pol):
02152     index = OpenRTM_aist.CORBA_SeqUtil.find(self._profile.interfaces,
02153                                             self.find_interface(name, pol))
02154 
02155     if index < 0:
02156       return False
02157 
02158     OpenRTM_aist.CORBA_SeqUtil.erase(self._profile.interfaces, index)
02159     return True
02160 
02161 
02162   ##
02163   # @if jp
02164   #
02165   # @brief PortProfile の properties に NameValue 値を追加する
02166   #
02167   # PortProfile の properties に NameValue 値を追加する。
02168   # 追加するデータの型をValueTypeで指定する。
02169   #
02170   # @param self
02171   # @param key properties の name
02172   # @param value properties の value
02173   #
02174   # @else
02175   #
02176   # @brief Add NameValue data to PortProfile's properties
02177   #
02178   # @param key The name of properties
02179   # @param value The value of properties
02180   #
02181   # @endif
02182   #  template <class ValueType>
02183   #  void addProperty(const char* key, ValueType value)
02184   def addProperty(self, key, value):
02185     OpenRTM_aist.CORBA_SeqUtil.push_back(self._profile.properties,
02186                                          OpenRTM_aist.NVUtil.newNV(key, value))
02187 
02188   ##
02189   # @if jp
02190   #
02191   # @brief PortProfile の properties に NameValue 値を要素に追加する
02192   #
02193   # PortProfile の properties に NameValue 値を要素に追加する。
02194   #
02195   # @param key properties の name
02196   # @param value properties の value
02197   #
02198   # @else
02199   #
02200   # @brief Append NameValue data to PortProfile's properties
02201   #
02202   # Append NameValue data to PortProfile's properties.
02203   #
02204   # @param key The name of properties
02205   # @param value The value of properties
02206   #
02207   # @endif
02208   # void appendProperty(const char* key, const char* value)
02209   def appendProperty(self, key, value):
02210     OpenRTM_aist.NVUtil.appendStringValue(self._profile.properties, key, value)
02211 
02212 
02213 
02214   ##
02215   # @if jp
02216   #
02217   # @brief 存在しないポートをdisconnectする。
02218   #
02219   # @else
02220   #
02221   # @brief Disconnect ports that doesn't exist. 
02222   #
02223   # @endif
02224   # void updateConnectors()
02225   def updateConnectors(self):
02226     guard = OpenRTM_aist.ScopedLock(self._profile_mutex)
02227     
02228     connector_ids = []
02229     clist = self._profile.connector_profiles
02230 
02231     for cprof in clist:
02232       if not self.checkPorts(cprof.ports):
02233         connector_ids.append(cprof.connector_id)
02234         self._rtcout.RTC_WARN("Dead connection: %s", cprof.connector_id)
02235 
02236     for cid in connector_ids:
02237       self.disconnect(cid)
02238 
02239     return
02240 
02241 
02242   ##
02243   # @if jp
02244   #
02245   # @brief ポートの存在を確認する。
02246   #
02247   # @param ports 確認するポート
02248   # @return true:存在する,false:存在しない
02249   #
02250   # @else
02251   #
02252   # @brief Existence of ports
02253   #
02254   # @param ports Checked ports
02255   # @return true:existent,false:non existent
02256   #
02257   # @endif
02258   # bool checkPorts(::RTC::PortServiceList& ports)
02259   def checkPorts(self, ports):
02260     for port in ports:
02261       try:
02262         if port._non_existent():
02263           self._rtcout.RTC_WARN("Dead Port reference detected.")
02264           return False
02265       except:
02266         self._rtcout.RTC_WARN(OpenRTM_aist.Logger.print_exception())
02267         return False
02268 
02269     return True
02270 
02271 
02272   #inline void onNotifyConnect(const char* portname,
02273   #                            RTC::ConnectorProfile& profile)
02274   def onNotifyConnect(self, portname, profile):
02275     if self._portconnListeners != None:
02276       type = OpenRTM_aist.PortConnectListenerType.ON_NOTIFY_CONNECT
02277       self._portconnListeners.portconnect_[type].notify(portname, profile)
02278     return
02279 
02280 
02281   #inline void onNotifyDisconnect(const char* portname,
02282   #                               RTC::ConnectorProfile& profile)
02283   def onNotifyDisconnect(self, portname, profile):
02284     if self._portconnListeners != None:
02285       type = OpenRTM_aist.PortConnectListenerType.ON_NOTIFY_DISCONNECT
02286       self._portconnListeners.portconnect_[type].notify(portname, profile)
02287     return
02288 
02289 
02290   #inline void onUnsubscribeInterfaces(const char* portname,
02291   #                                    RTC::ConnectorProfile& profile)
02292   def onUnsubscribeInterfaces(self, portname, profile):
02293     if self._portconnListeners != None:
02294       type = OpenRTM_aist.PortConnectListenerType.ON_UNSUBSCRIBE_INTERFACES
02295       self._portconnListeners.portconnect_[type].notify(portname, profile)
02296     return
02297 
02298 
02299   #inline void onPublishInterfaces(const char* portname,
02300   #                                RTC::ConnectorProfile& profile,
02301   #                                ReturnCode_t ret)
02302   def onPublishInterfaces(self, portname, profile, ret):
02303     if self._portconnListeners != None:
02304       type = OpenRTM_aist.PortConnectRetListenerType.ON_PUBLISH_INTERFACES
02305       self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
02306     return
02307 
02308 
02309   #inline void onConnectNextport(const char* portname,
02310   #                              RTC::ConnectorProfile& profile,
02311   #                              ReturnCode_t ret)
02312   def onConnectNextport(self, portname, profile, ret):
02313     if self._portconnListeners != None:
02314       type = OpenRTM_aist.PortConnectRetListenerType.ON_CONNECT_NEXTPORT
02315       self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
02316     return
02317 
02318 
02319   #inline void onSubscribeInterfaces(const char* portname,
02320   #                                  RTC::ConnectorProfile& profile,
02321   #                                  ReturnCode_t ret)
02322   def onSubscribeInterfaces(self, portname, profile, ret):
02323     if self._portconnListeners != None:
02324       type = OpenRTM_aist.PortConnectRetListenerType.ON_SUBSCRIBE_INTERFACES
02325       self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
02326     return
02327 
02328 
02329   #inline void onConnected(const char* portname,
02330   #                        RTC::ConnectorProfile& profile,
02331   #                        ReturnCode_t ret)
02332   def onConnected(self, portname, profile, ret):
02333     if self._portconnListeners != None:
02334       type = OpenRTM_aist.PortConnectRetListenerType.ON_CONNECTED
02335       self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
02336     return
02337 
02338 
02339   #inline void onDisconnectNextport(const char* portname,
02340   #                                 RTC::ConnectorProfile& profile,
02341   #                                 ReturnCode_t ret)
02342   def onDisconnectNextport(self, portname, profile, ret):
02343     if self._portconnListeners != None:
02344       type = OpenRTM_aist.PortConnectRetListenerType.ON_DISCONNECT_NEXT
02345       self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
02346     return
02347 
02348 
02349   #inline void onDisconnected(const char* portname,
02350   #                           RTC::ConnectorProfile& profile,
02351   #                           ReturnCode_t ret)
02352   def onDisconnected(self, portname, profile, ret):
02353     if self._portconnListeners != None:
02354       type = OpenRTM_aist.PortConnectRetListenerType.ON_DISCONNECTED
02355       self._portconnListeners.portconnret_[type].notify(portname, profile, ret)
02356     return
02357 
02358 
02359 
02360   #============================================================
02361   # Functor
02362   #============================================================
02363 
02364   ##
02365   # @if jp
02366   # @class if_name
02367   # @brief instance_name を持つ PortInterfaceProfile を探す Functor
02368   # @else
02369   # @brief A functor to find a PortInterfaceProfile named instance_name
02370   # @endif
02371   class if_name:
02372     def __init__(self, name):
02373       self._name = name
02374 
02375     def __call__(self, prof):
02376       return str(self._name) == str(prof.instance_name)
02377     
02378 
02379   ##
02380   # @if jp
02381   # @class find_conn_id
02382   # @brief id を持つ ConnectorProfile を探す Functor
02383   # @else
02384   # @brief A functor to find a ConnectorProfile named id
02385   # @endif
02386   class find_conn_id:
02387     def __init__(self, id_):
02388       """
02389        \param id_(string)
02390       """
02391       self._id = id_
02392 
02393     def __call__(self, cprof):
02394       """
02395        \param cprof(RTC.ConnectorProfile)
02396       """
02397       return str(self._id) == str(cprof.connector_id)
02398 
02399   ##
02400   # @if jp
02401   # @class find_port_ref
02402   # @brief コンストラクタ引数 port_ref と同じオブジェクト参照を探す Functor
02403   # @else
02404   # @brief A functor to find the object reference that is identical port_ref
02405   # @endif
02406   class find_port_ref:
02407     def __init__(self, port_ref):
02408       """
02409        \param port_ref(RTC.PortService)
02410       """
02411       self._port_ref = port_ref
02412 
02413     def __call__(self, port_ref):
02414       """
02415        \param port_ref(RTC.PortService)
02416       """
02417       return self._port_ref._is_equivalent(port_ref)
02418 
02419   ##
02420   # @if jp
02421   # @class connect_func
02422   # @brief Port の接続を行う Functor
02423   # @else
02424   # @brief A functor to connect Ports
02425   # @endif
02426   class connect_func:
02427     def __init__(self, p, prof):
02428       """
02429        \param p(RTC.PortService)
02430        \param prof(RTC.ConnectorProfile)
02431       """
02432       self._port_ref = p
02433       self._connector_profile = prof
02434       self.return_code = RTC.RTC_OK
02435 
02436     def __call__(self, p):
02437       """
02438        \param p(RTC.PortService)
02439       """
02440       if not self._port_ref._is_equivalent(p):
02441         retval = p.notify_connect(self._connector_profile)
02442         if retval != RTC.RTC_OK:
02443           self.return_code = retval
02444 
02445   ##
02446   # @if jp
02447   # @class disconnect_func
02448   # @brief Port の接続解除を行う Functor
02449   # @else
02450   # @brief A functor to disconnect Ports
02451   # @endif
02452   class disconnect_func:
02453     def __init__(self, p, prof):
02454       """
02455        \param p(RTC.PortService)
02456        \param prof(RTC.ConnectorProfile)
02457       """
02458       self._port_ref = p
02459       self._connector_profile = prof
02460       self.return_code = RTC.RTC_OK
02461       
02462     def __call__(self, p):
02463       """
02464        \param p(RTC.PortService)
02465       """
02466       if not self._port_ref._is_equivalent(p):
02467         retval = p.disconnect(self._connector_profile.connector_id)
02468         if retval != RTC.RTC_OK:
02469           self.return_code = retval
02470 
02471   ##
02472   # @if jp
02473   # @class disconnect_all_func
02474   # @brief Port の全接続解除を行う Functor
02475   # @else
02476   # @brief A functor to disconnect all Ports
02477   # @endif
02478   class disconnect_all_func:
02479     def __init__(self, p):
02480       """
02481        \param p(OpenRTM_aist.PortBase)
02482       """
02483       self.return_code = RTC.RTC_OK
02484       self._port = p
02485 
02486     def __call__(self, p):
02487       """
02488        \param p(RTC.ConnectorProfile)
02489       """
02490       retval = self._port.disconnect(p.connector_id)
02491       if retval != RTC.RTC_OK:
02492         self.return_code = retval
02493 
02494   ##
02495   # @if jp
02496   # @class find_interface
02497   # @brief name と polarity から interface を探す Functor
02498   # @else
02499   # @brief A functor to find interface from name and polarity
02500   # @endif
02501   class find_interface:
02502     def __init__(self, name, pol):
02503       """
02504        \param name(string)
02505        \param pol(RTC.PortInterfacePolarity)
02506       """
02507       self._name = name
02508       self._pol = pol
02509 
02510     def __call__(self, prof):
02511       """
02512        \param prof(RTC.PortInterfaceProfile)
02513       """
02514       name = prof.instance_name
02515       return (str(self._name) == str(name)) and (self._pol == prof.polarity)


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