いつも御世話になります。宇田@NECシステムテクノロジーです
以前にこちらのメーリングリストで、安藤様から非同期呼び出し時の コールバックにつきまして下記の方法をご紹介頂いたかと思いますが、 こちらで試させて頂きましたところ、コンシューマ→プロバイダ間を 多対1にリンクした場合に、必ずしも呼出元のコンシューマに対して コールバックが掛からない状況に遭遇しました。
┌───────┐ │ │ do()→ │ コンシューマ □─────┐ │ │ │ └───────┘ │ │ ┌───────┐ │ done() ┌───────┐ │ │ do()→ │ ?← │ │ │ コンシューマ □─────┼─────□ プロバイダ │ │ │ │ │ │ └───────┘ │ └───────┘ │ ┌───────┐ │ │ │ do()→ │ │ コンシューマ □─────┘ │ │ └───────┘
そこで、サービスポートにCallbackサービスを登録する代りに、下記 のdo()オペレーションの引数にCallbackオブジェクトを渡し、オペレ ーションの終了時にこのCallbackオブジェクトのdone()を呼ぶ方式を 採りたいのですが、OpenRTMのコーディングスタイルとして、このよう に実装しても問題ございませんでしょうか?
┌───────┐ │ │ do(cb)→ │ コンシューマ □─────┐ │ │ │ └───────┘ │ │ ┌───────┐ │cb->done()┌───────┐ │ │ do(cb)→ │ ← │ │ │ コンシューマ □─────┼─────□ プロバイダ │ │ │ │ │ │ └───────┘ │ └───────┘ │ ┌───────┐ │ │ │ do(cb)→ │ │ コンシューマ □─────┘ │ │ └───────┘
また具体的な実装方法としては下記を想定しているのですが、実装上 まずい箇所などがございましたらご教授頂けますでしょうか?
よろしくお願い申し上げます。
Callback.idl ┌───────────┐ │interface Callback │ │{ │ │ void done(); │ │}; │ └───────────┘
MyService.idl ┌──────────────────┐ │#include "Callback.idl" │ │interface MyService │ │{ │ │ oneway void do(in Callback cb); │ │}; │ └──────────────────┘
gen.sh ┌─────────────────────────┐ │#!/bin/sh │ │rtc-template -bcxx \ │ │ ・・・ │ │ --service=MyService:myservice0:MyService \ │ │ --service-idl=MyService.idl \ │ │ --consumer-idl=Callback.idl │← 追加 │ │ │rtc-template -bcxx \ │ │ ・・・ │ │ --consumer=MyService:myservice0:MyService \ │ │ --consumer-idl=MyService.idl \ │ │ --service-idl=Callback.idl │← 追加 └─────────────────────────┘
MyServiceConsumer.h ┌─────────────────┐ │class MyServiceConsumer │ │{ │ │ ・・・ │ │ private: │ │ CallbackSVC_impl m_callback; │ │ Callback_var m_callback_ref; │ │} │ └─────────────────┘
MyServiceConsumer.cpp ┌──────────────────────────────────────┐ │MyServiceConsumer::MyServiceConsumer(RTC::Manager* manager) │ │ ・・・ │ │{ │ │ ・・・ │ │ PortableServer::ObjectId_var oid; │ │ CORBA::Object_var oref; │ │ oid = _default_POA()->activate_object(&m_callback); │ │ oref = _default_POA()->create_reference_with_id(oid, _tc_Callback->id()); │ │ m_callback_ref = Callback::_narrow(oref); │ │ ・・・ │ │} │ │ │ │ │ │RTC::ReturnCode_t MyServiceConsumer::onExecute(RTC::UniqueId ec_id) │ │{ │ │ ・・・ │ │ m_myservice0->do(m_callback_ref); │ │ ・・・ │ │} │ └──────────────────────────────────────┘
MyServiceSVC_impl.cpp ┌───────────────────────┐ │void MyServiceSVC_impl::do(Callback_ptr cb) │ │{ │ │ ・・・ │ │ cb->done(); │ │} │ └───────────────────────┘
> あるサービスポートのプロバイダ側で、 > > interface MyService > { > oneway void do(); > }; > > という、サービスプロバイダを持たせ、かつ同じポートに、 > > interface Callback > { > void done(); > }; > > のような、コンシューマを持たせます。 > > サービスコンシューマの方は、これと逆にプロバイダとコンシューマを持たせます。 > つまり、 > - MyService のコンシューマ > - Callbackのプロバイダ > を持つことになります。 > これらのプロバイダとコンシューマはポートを接続することにより相互に接続されます。 > > MyServiceのプロバイダ側では、do()の処理が終わったら、 > そのコンシューマのdone()を呼んでやることで、呼び出し側に > 処理が終わったことを知らせることが可能です。
モーションエディタ/シミュレータ
動力学シミュレータ
統合開発プラットフォーム
産総研が提供するRTC集
東京オープンソースロボティクス協会
ネットワーク分散環境でデータ収集用ソフトウェアを容易に構築するためのソフトウェア・フレームワーク
いつも御世話になります。宇田@NECシステムテクノロジーです
以前にこちらのメーリングリストで、安藤様から非同期呼び出し時の
コールバックにつきまして下記の方法をご紹介頂いたかと思いますが、
こちらで試させて頂きましたところ、コンシューマ→プロバイダ間を
多対1にリンクした場合に、必ずしも呼出元のコンシューマに対して
コールバックが掛からない状況に遭遇しました。
┌───────┐
│ │ do()→
│ コンシューマ □─────┐
│ │ │
└───────┘ │
│
┌───────┐ │ done() ┌───────┐
│ │ do()→ │ ?← │ │
│ コンシューマ □─────┼─────□ プロバイダ │
│ │ │ │ │
└───────┘ │ └───────┘
│
┌───────┐ │
│ │ do()→ │
│ コンシューマ □─────┘
│ │
└───────┘
そこで、サービスポートにCallbackサービスを登録する代りに、下記
のdo()オペレーションの引数にCallbackオブジェクトを渡し、オペレ
ーションの終了時にこのCallbackオブジェクトのdone()を呼ぶ方式を
採りたいのですが、OpenRTMのコーディングスタイルとして、このよう
に実装しても問題ございませんでしょうか?
┌───────┐
│ │ do(cb)→
│ コンシューマ □─────┐
│ │ │
└───────┘ │
│
┌───────┐ │cb->done()┌───────┐
│ │ do(cb)→ │ ← │ │
│ コンシューマ □─────┼─────□ プロバイダ │
│ │ │ │ │
└───────┘ │ └───────┘
│
┌───────┐ │
│ │ do(cb)→ │
│ コンシューマ □─────┘
│ │
└───────┘
また具体的な実装方法としては下記を想定しているのですが、実装上
まずい箇所などがございましたらご教授頂けますでしょうか?
よろしくお願い申し上げます。
Callback.idl
┌───────────┐
│interface Callback │
│{ │
│ void done(); │
│}; │
└───────────┘
MyService.idl
┌──────────────────┐
│#include "Callback.idl" │
│interface MyService │
│{ │
│ oneway void do(in Callback cb); │
│}; │
└──────────────────┘
gen.sh
┌─────────────────────────┐
│#!/bin/sh │
│rtc-template -bcxx \ │
│ ・・・ │
│ --service=MyService:myservice0:MyService \ │
│ --service-idl=MyService.idl \ │
│ --consumer-idl=Callback.idl │← 追加
│ │
│rtc-template -bcxx \ │
│ ・・・ │
│ --consumer=MyService:myservice0:MyService \ │
│ --consumer-idl=MyService.idl \ │
│ --service-idl=Callback.idl │← 追加
└─────────────────────────┘
MyServiceConsumer.h
┌─────────────────┐
│class MyServiceConsumer │
│{ │
│ ・・・ │
│ private: │
│ CallbackSVC_impl m_callback; │
│ Callback_var m_callback_ref; │
│} │
└─────────────────┘
MyServiceConsumer.cpp
┌──────────────────────────────────────┐
│MyServiceConsumer::MyServiceConsumer(RTC::Manager* manager) │
│ ・・・ │
│{ │
│ ・・・ │
│ PortableServer::ObjectId_var oid; │
│ CORBA::Object_var oref; │
│ oid = _default_POA()->activate_object(&m_callback); │
│ oref = _default_POA()->create_reference_with_id(oid, _tc_Callback->id()); │
│ m_callback_ref = Callback::_narrow(oref); │
│ ・・・ │
│} │
│ │
│ │
│RTC::ReturnCode_t MyServiceConsumer::onExecute(RTC::UniqueId ec_id) │
│{ │
│ ・・・ │
│ m_myservice0->do(m_callback_ref); │
│ ・・・ │
│} │
└──────────────────────────────────────┘
MyServiceSVC_impl.cpp
┌───────────────────────┐
│void MyServiceSVC_impl::do(Callback_ptr cb) │
│{ │
│ ・・・ │
│ cb->done(); │
│} │
└───────────────────────┘
> あるサービスポートのプロバイダ側で、
>
> interface MyService
> {
> oneway void do();
> };
>
> という、サービスプロバイダを持たせ、かつ同じポートに、
>
> interface Callback
> {
> void done();
> };
>
> のような、コンシューマを持たせます。
>
> サービスコンシューマの方は、これと逆にプロバイダとコンシューマを持たせます。
> つまり、
> - MyService のコンシューマ
> - Callbackのプロバイダ
> を持つことになります。
> これらのプロバイダとコンシューマはポートを接続することにより相互に接続されます。
>
> MyServiceのプロバイダ側では、do()の処理が終わったら、
> そのコンシューマのdone()を呼んでやることで、呼び出し側に
> 処理が終わったことを知らせることが可能です。