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)