KOM を使う / OpenParts の使い方
前のページ | 第 2章KDE オブジェクトモデル (KOM) | 次のページ

# 2.3. イベント

イベントは2つの要素、イベントネームつまり文字列とイベント引数 CORBA::Any value で 成り、それゆえ開発者は自由に選択できます。

指定されたオブジェクトに送られたイベントは、イベントが目的地となるオブジェクトまでの パイプを通されていると考えることができます。 このパイプはインストールされているイベントフィルタで満たされています。 フィルタには三種類があります。

- 読み込みフィルタ ( `FM_READ`)

- 書き込みフィルタ ( `FM_WRITE`)

- 実行フィルタ ( `FM_IMPLEMENT`)

KOM の現在の実装では、これらのフィルタモードはイベント処理の命令を指示するだけです。 イベントが発信される場合、まずフィルタモード`FM_WRITE`で全てのイベントフィルタがフィルタリングされます。 そして`FM_IMPLEMENT`に続き、 最終的に`FM_READ`と続きます。 イベントフィルタには実際のイベントで行うことができる二つの可能性があります。 これらのフィルタはイベントを単に読み込むだけ可、 あるいはそのイベントを廃棄することができます。 つまりそのイベントは破棄され、その行き先のオブジェクトを決して受け取らないということです。

実際のイベントネームは、イベントフィルタに関して特別な意味を持っています。 あるオブジェクトに対してイベントフィルタをインストールした場合、 フィルタオブジェクトのリファレンスやフィルタマッピング機能の名称に加えて、 一連のいわゆるイベントタイプパターンについても指示しなければなりません。 あるイベントタイプパターンは、特別なパターンだけではなく単一のイベント名称です。 (イベントパターンについて、詳しくは`kom.idl`を ご覧ください)。

イベントがフィルタによって処理される際、引数としてのイベントネームとイベント値で 指定されたフィルタ関数が呼ばれます。 このフィルタ関数は、イベントが廃棄されるかどうかを(ブール値を通じて) 返さなければなりません。

全てのフィルタリングが実行され、インストールされたどのフィルタがイベントを破棄しない場合、最終的に行き先のオブジェクトによって受け取られます。 つまり、オブジェクトの`event()`メソッドを呼ぶことによって KOM::Base インターフェースに定義されます。 デフォルトの実装は実際には何も行いません。 ですからもしかするとこの仮想関数の再実装が必要になるかもしれません。

イベントの低レベルな使用方法は、イベント送信用オブジェクトの receive/receiveASyncメソッドを呼んだり、イベントをマッピングするために KOMBase::event を 再インプリメントすることです。 しかし KOM には、イベント処理を単純化する素晴らしいマクロがいくつか用意されています。

## 2.3.1. イベントの送信

送信用に komBase.h は、役立つ`EMIT_EVENT`マクロを定義してあり、全て同じ文法`EMIT_EVENT_x(destination_object, event_name, event_argument)`を使用しています。

"destination_object" は、イベントの受け取り/処理を予定しているオブジェクトのリファレンスです。 イベントは、この目的オブジェクトにインストールされている全てのイベントフィルタで処理されます。 "event_name" は、自明でしょう;-)。 イベント引数は、特定のマクロに従います。それらは特に以下のようなものです：

- `EMIT_EVENT`, 送信用一般的なマクロです。 イベント引数には、CORBA::Any で定義された `<<=`演算子が必要です。 イベント引数が例えば一つの構造である時は必ずこのマクロを使う必要性があるでしょう。 ("--any"を使って idlファイルをコンパイルすることを忘れないでください。idlコンパイラは必要な演算子メソッドを作成してくれます。)

- `EMIT_EVENT_BOOLEAN`, ブールイベント引数に便利です。 `EMIT_EVENT`マクロとの違いは、ブール値を変換するのに CORBA::Any::from_boolean を使うことです。 ですから、以下のものをどう使うかは実際は問題ではありません。 `EMIT_EVENT( receiver, name, CORBA::Any::from_boolean( value ) );` または `EMIT_EVENT_BOOLEAN( receiver, name, value );`

- `EMIT_EVENT_OCTET`,EMIT_EVENT_BOOLEAN と類似しCORBA::Octet値に使用できます。

- `EMIT_EVENT_CHAR`,EMIT_EVENT_BOOLEANと類似し、char (CORBA::Char)値に使用できます。

- `EMIT_EVENT_WCHAR`,EMIT_EVENT_BOOLEANと類似し、CORBA::WChar値に使用できます。

- `EMIT_EVENT_STRING`, EMIT_EVENT_BOOLEANと類似し、char *(CORBA::Char*)値に使用できます。

- `EMIT_EVENT_WSTRING`, EMIT_EVENT_BOOLEANと類似し、CORBA::WChar*値に使用できます。

- `EMIT_EVENT_OBJECT`, EMIT_EVENT_BOOLEANと類似し、CORBAオブジェクト (CORBA::Object)に使用できます。

## 2.3.2. イベントの受信

イベントの受信は送信に比べて若干困難です。 というのは、あらゆる種類のイベントを処理しなければならないので、 オブジェクトは1つのハンドラメソッド KOM::Base ::event (IDL) / KOMBase::event (C++)で受け取ることができるます。 イベントの送信のように、低CORBAレベルで全てのことを行うことができます。 しかし、なぜ堅実な方法を採ろうとするのでしょう？ KOMは、これに関してもとても素晴らしく、使いやすいマクロがあります(komBase.hで定義されています):-)。 たいていが次のサンプルのような感じになっています:

       1 #include <kom.idl>
       2
       3 module MyModule
       4 {
       5   // イベント引数は文字列
       6   const string eventFirstFoo = "MyFooEventNameOrWhateverYouNameIt";
       7
       8   struct MyStruct
       9   {
      10     boolean kde_rules;
      11   };
      12
      13   const string eventSecondFoo = "Blaafooo";
      14   typedef MyStruct EventSecondFoo;
      15
      16   interface SomethingElse
      17   {
      18     //..
      19   };
      20
      21   const string eventThirdFoo = "KOMIsCool";
      22   typedef SomethingElse EventThirdFoo;
      23
      24   interface Foo : KOM::Base
      25   {
      26     //...
      27   };
      28
      29 };
      30
      31 bool FooImpl::event( const char *event, const CORBA::Any &value )
      32 {
      33   EVENT_MAPPER( event, value );
      34
      35   MAPPING_STRING( MyModule::eventFirstFoo, mappingFirstFoo );
      36
      37   MAPPING( MyModule::eventSecondFoo, MyModule::EventSecondFoo, mappingSecondFoo );
      38
      39   MAPPING( MyModule::eventThirdFoo, MyModule::EventThirdFoo_ptr, mappingThirdFoo );
      40
      41   END_EVENT_MAPPER; //マクロは "return false;" を実行します。
      42                     //このポイントに達したときイベントを取り扱わなかったことを示します。
      43 }
      44
      45 bool FooImpl::mappingFirstFoo( const char *myArgument )
      46 {
      47   ...
      48   //忘れずにブール値を用いて返して下さい。
      49   //イベント処理が成功したかどうかを暗示します。
      50 }
      51
      52 bool FooImpl::mappingSecondFoo( MyModule::MyString anotherArg )
      53 {
      54   //...
      55 }
      56
      57 bool FooImpl::mappingThirdFoo( MyModule::SomethingElse_ptr whaaboo )
      58 {
      59   //...
      60 }

ご覧のように、イベントハンドラはたいてい`EVENT_MAPPER`マクロで始まっており、`END_EVENT_MAPPER`で終わっています。 `EMIT_EVENT_x`マクロと類似し、 `MAPPING`マクロは通常の`MAPPING`マクロと以下のものから構成されています：

- `MAPPING_BOOLEAN`

- `MAPPING_OCTET`

- `MAPPING_CHAR`

- `MAPPING_WCHAR`

- `MAPPING_STRING`

- `MAPPING_WSTRING`

- `MAPPING_OBJECT`

多少イベント処理を構造化するには、どのイベントも関数を取り扱っている独自のイベントを得ます。 これらの関数はマッピングマクロ(最後の引数)で呼ばれます。 上記で用いられたネーミングスキームは、必要ではありませんが、KOMを使用しているアプリケーションではだいたい用いられています。

前のページ | Home | 次のページ
シグナルとスロット | Up | Adopting