![]() ![]() ![]() ![]() |
SophiaFramework UNIVERSE 5.2 |
イベントの処理は、以下のようにして行われます。
![]() |
イベントの配信について |
---|---|
SFYResponder::Distribute 関数は、 この関数を呼び出した時点のレスポンダツリー上のレスポンダにイベントを配信します。 イベントループ内で新規に作成されたレスポンダには配信しません。 また、 SFYResponder::Terminate 関数により破棄されたレスポンダにも配信しません。 |
例 9.22. SFYApplication::HandleEvent 関数の内部実装
// アプリが BREW 環境からイベントを受信したときに呼び出される関数 /*protected virtual */Bool SFYApplication::HandleEvent(SFXEventConstRef event) { SFCError error; Bool result(false); // 配信エンジンを起動してイベントを配信する // ※ イベントは最初にルートに関連付けられた SFYDistributer インスタンスに配信される // その後、トレーサの配信規則に基づいてルート以下のレスポンダツリーに配信される if ((error = _root->Distribute(event, &result)) == SFERR_NO_ERROR) { // (_root はルート、result 引数にはイベントの処理結果が格納される) if (result) { // イベントが処理された場合 if (IsRenderable()) { // 優先的イベントハンドラが登録されていない場合 // 描画エンジンを起動して再描画を行う error = _root->Render(); } } } if (error != SFERR_NO_ERROR) { // 配信エンジンや描画エンジンの起動時にメモリ不足などの致命的エラーが発生した場合 if (HandleError(event, error)) { result = true; } } return result; // イベントを処理したときは true を返し, そうでないときは false を返す }// SFYApplication::HandleEvent //
参照: SFYResponder::Distribute | SFYResponder::Render | SFCApplication::HandleEvent | SFCApplication::IsRenderable | SFCApplication::HandleError | SFZRoot | ルート | トレーサ | 配信エンジン | 描画エンジン
![]() |
優先的イベントハンドラ |
---|---|
SFXEventBypass クラスの解説を参照してください。 |
アプリの起動から終了までの間には、 開始、終了、サスペンド、レジューム、キー操作など、 様々なイベントが BREW 環境からアプリへ送信されます。
アプリでは、 これらのイベントを受信しハンドラを呼び出すというイベントドリブンな処理が繰り返されます。
以下は、アプリの典型的なライフサイクルの内容です。
図 9.17. ライフサイクル
アプリが受信するさまざまなイベントを分岐処理するのは非常に煩雑です。
SophiaFramework UNIVERSE では、 配信エンジンがイベントの分岐処理を自動的に行うので、 プログラム構造はシンプルです。
ユーザーがアプリを起動すると、 最初に SFYApplication クラスを継承するアプリケーションクラスのインスタンスが作成されます。
SFYApplication::SFYApplication コンストラクタは、 配信エンジンと描画エンジンを初期化し、 それらが関連付けられたルートを作成します。
その後、 アプリは BREW 環境から SFEVT_APP_START イベントを受信し、 アプリの初期化を行います。
![]() |
アプリの初期化処理 |
---|---|
レスポンダの作成などアプリの初期化処理は、 アプリケーションクラスのコンストラクタ内の処理、または SFEVT_APP_START イベントへの応答として実装します。 |
終了メニューや電源キーによってアプリを終了すると、 アプリは 最初に BREW 環境から SFEVT_APP_NO_CLOSE イベントを受信します。
このイベントには false を返します (true を返した場合、アプリは終了しません)。
そして、アプリは BREW 環境から SFEVT_APP_STOP イベントを受信し、 終了処理を行います。
SFEVT_APP_STOP イベントの処理が正常に終了した場合、 SFYApplication::~SFYApplication デストラクタは、 配信エンジン、描画エンジン、ルート、アプリケーションクラスやウィンドウなどレスポンダのインスタンスを解放します。
![]() |
アプリの終了処理 |
---|---|
レスポンダの破棄などのアプリの終了処理は、 アプリケーションクラスのデストラクタ内の処理、または SFEVT_APP_STOP イベントへの応答として実装します。 |
図 9.19. アプリの終了
上の図では、 ユーザーがウィンドウ(win1)上の終了ボタンを押下した後、 SFCApplication::Terminate 関数が実行されアプリが終了することを想定しています。
※ 終了時のシーケンスと関係の薄い描画エンジンとルートは図から省略されています。
トレーサは、 SFYResponder::Distribute 関数を使用してレスポンダにイベントを配信する規則を管理しています。
標準トレーサとは、 配信エンジン (SFYApplication クラスが内部で保持するルートに設定された SFYDistributer インスタンス)のトレーサのことです。 下記の表にあるように、一般のアプリ開発に必要十分なデフォルトの配信規則が予め登録されています。
トレーサの登録内容を変更しない場合、 イベントの配信は標準トレーサを利用して行われます。 ルートは標準トレーサの設定を継承し、 子レスポンダは親レスポンダのトレーサの設定を継承します。
![]() |
標準トレーサのカスタマイズについて |
---|---|
ほとんどのアプリ開発において、 標準トレーサの設定内容をカスタマイズする必要はありません。 |
トレーサに登録する配信規則には、以下の 3 つの要素があります。
■配信条件
配信条件は、 イベントを配信するレスポンダの状態を表します。
以下のいずれかを指定します。
キーイベントでは、配信条件が『フォーカス[SFYTracer::STATE_FOCUS]』に設定されているので、 フォーカスされているレスポンダに配信されます。
アプリの開始、終了、サスペンド、レジュームのイベントでは、 配信条件が『すべて[SFYTracer::STATE_ALL]』に設定されているので、 有効状態が ON である、すべてのレスポンダに配信されます。
![]() |
標準トレーサに『配信条件: なし[SFYTracer::STATE_NONE]』で配信規則が登録されている BREW イベントを受信する方法 |
---|---|
標準トレーサに『配信条件: なし[SFYTracer::STATE_NONE]』 で配信規則が登録されているBREW イベントは、 SFYApplication が内部で保持するルートを含めレスポンダには配信されません。 これは標準トレーサの配信規則が SFYDistributer インスタンスに登録されているからです。 このイベントを受信するには、SFYDistributer インスタンスに直接ハンドラを登録する必要があります。 具体的には以下の方法で取得します。
|
■処理順序
処理順序は、 イベントを配信する順序とハンドラを呼び出す優先順位を表します。
以下のいずれかを指定します。
■重複条件
重複条件は、 ハンドラがイベントを重複して処理するかどうかを表します。
以下のいずれかを指定します。
SFEVT_KEY イベントは、 配信条件が『フォーカス[SFYTracer::STATE_FOCUS]』、 処理順序が『前面から背面[SFYTracer::ORDER_FORWARD]』に設定されているので、 前面から背面の順にフォーカスされているレスポンダに配信されます。 同じレスポンダに複数個のハンドラが登録されている場合は、ハンドラは登録の逆順に呼び出されます。 重複条件は『なし』に設定されているので、 イベントがハンドラによって処理されると、そこでイベント処理は終了します。
SFEVT_APP_RESUME イベントは、 配信条件が『すべて[SFYTracer::STATE_ALL]』、 処理順序が『背面から前面[SFYTracer::ORDER_BACKWARD]』に設定されているので、 背面から前面の順に状態に関係なく、 有効状態が ON である、すべてのレスポンダに配信されます。 同じレスポンダに複数個のハンドラが登録されている場合は、登録の順に呼び出されます。 重複条件は『あり』に設定されているので、 ハンドラのイベント処理に関係なく、無くなるまで継続して次のハンドラを呼び出します。
図 9.22. SFEVT_KEY イベント: 処理順序と重複条件
SFEVT_KEY イベントは、前面から背面の順に処理されます。
■標準トレーサの設定
標準トレーサの設定は以下の表のとおりです。
表 9.3. 標準トレーサ
イベントタイプ | 配信条件 | 処理順序 | 重複条件 |
---|---|---|---|
SFEVT_APP_START | すべて | 背面から前面 | あり |
SFEVT_APP_STOP | すべて | 前面から背面 | あり |
SFEVT_APP_RESUME | すべて | 背面から前面 | あり |
SFEVT_APP_SUSPEND | すべて | 前面から背面 | あり |
SFEVT_APP_CONFIG から SFEVT_APP_START_WINDOW | なし | 前面から背面 | なし |
SFEVT_KEY から SFEVT_KEY_HOOK_RELEASE | フォーカス | 前面から背面 | なし |
SFEVT_COMMAND から SFEVT_CTL_TEXT_MODECHANGED | フォーカス | 前面から背面 | なし |
SFEVT_DIALOG_INIT から SFEVT_COPYRIGHT_END | フォーカス | 前面から背面 | なし |
SFEVT_ALARM から SFEVT_NOTIFY_FAILURE | なし | 前面から背面 | なし |
SFEVT_FLIP から SFEVT_SCR_ROTATE | なし | 前面から背面 | なし |
SFEVT_CB_CUT から SFEVT_CB_PASTE | なし | 前面から背面 | なし |
![]() |
警告 |
---|---|
トレーサを利用して配信するイベントは、BREW イベントまたはユーザーイベントです。 レスポンダイベントはトレーサを利用して配信してはいけません。 ユーザーイベントを配信するには、トレーサに配信規則を登録する必要があります。 |
![]() |
標準トレーサに『配信条件: なし[SFYTracer::STATE_NONE]』で配信規則が登録されている BREW イベントを取得する方法 |
---|---|
標準トレーサに『配信条件: なし[SFYTracer::STATE_NONE]』 で配信規則が登録されているBREW イベントは、 SFYApplication が内部に保持する SFYDistributer インスタンスだけに配信されます (ルートを含めレスポンダには配信されません)。 この場合、 ハンドラを SFYDistributer インスタンスに登録して BREW イベントを処理する必要があります。 具体的には、以下のようにして行います。
|
例 9.23. トレーサへの配信規則の登録
USRResponder::USRResponder(Void) static_throws { if (static_try()) { // ...(省略)... static_throw(RegisterTracer( SFXEventRange(SFEVT_KEY, SFEVT_KEY, AVK_SOFT1, AVK_SOFT4), SFYTracer::ORDER_FORWARD, SFYTracer::STATE_ALL, false )); // ...(省略)... } }
![]() |
Tip |
---|---|
配信規則は SFYResponder::RegisterTracer / SFYDistributer::RegisterTracer 関数を使用してトレーサに登録します。 |
ハンドラとは、 レスポンダが受信したイベントを処理する関数のことです。
ハンドラは、 SFYResponder::RegisterHandler / SFYDistributer::RegisterHandler 関数を使用してレスポンダやルートに設定された SFYDistributer インスタンスにイベントと関連付けて登録します。
ハンドラは、同じイベントに対して複数個登録できます。
例えば、 複数のハンドラをセレクトキーの SFEVT_KEY イベントに関連付けてウィンドウに登録したとします。
SFEVT_KEY イベントに関する 標準トレーサに登録された配信規則の処理順序は 「前面から背面」なので、 ウィンドウが SFEVT_KEY イベントを受信すると、 最後に登録したハンドラが最初に呼び出されます。
このハンドラが true を返すと、イベント処理はここで終了します。 false を返した場合は、 最後から 2 番目に登録したハンドラが呼び出されます。
このウィンドウのイベント処理は、何れかのハンドラが true を返すか、 ウィンドウに登録されたハンドラが無くなるまで続けられます。
どのハンドラにも処理されなかった場合は、 ウィンドウよりももう 1 つ背面にあるフォーカスされているレスポンダで同様の処理が行われます。
![]() |
ハンドラの配置関係 |
---|---|
ハンドラは、背面から前面へ登録順に配置されます (最初に登録されたハンドラは最背面、最後に登録されたハンドラは最前面に配置されます)。 |
例 9.24. ハンドラの登録
USRResponder::USRResponder(Void) static_throws { if (static_try()) { // ...(省略)... static_throw(RegisterHandler( SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END), XANDLER_INTERNAL(OnKey) )); // ...(省略)... } }
例 9.25. ハンドラの実装
XANDLER_IMPLEMENT_BOOLEVENT(USRResponder, OnKey, invoker, event) { switch (event.GetP16()) { case AVK_SELECT: TRACE("select key was pressed."); return true; case AVK_CLR: TRACE("clear key was pressed."); return true; default: TRACE("unknown key was pressed."); return true; } return false; }
![]() |
重要 |
---|---|
ハンドラは、イベントを処理したときは true、 しなかったときは false を返すように実装します。 イベントループ内の処理で 1 つ以上のハンドラが true を返した場合、 レスポンダシステムは SFYResponder::Render 関数を呼び出して描画エンジンを起動し、 再描画を行います。 参照: SFYApplication::HandleEvent 関数の内部実装 |
参照: ハンドラ | イベント | SFYResponder::RegisterHandler | SFYDistributer::RegisterHandler | SFYApplication::HandleEvent
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |
![]() ![]() ![]() ![]() |