![]() ![]() ![]() ![]() |
SophiaFramework UNIVERSE 5.2 |
#include <SFCApplication.h.hpp>
class SFCApplication : public SFCInvoker;
SFMTYPEDEFCLASS(SFCApplication)
■ 仕様と使い方
すべてのアプリケーションクラスは SFCApplication クラスを継承します。
![]() |
注意 |
---|---|
SFCApplication クラスを直接継承したアプリケーションクラスを使用する場合、 必要な初期設定を行わない限り SFY レスポンダシステムを利用できません。 通常、SFY レスポンダシステムを利用するには、 必要な初期設定が予め実装されている SFYApplication クラスを継承してアプリケーションクラスを作成します。 詳しくは ルートの解説を参照してください。 |
■イベント処理 −全体的な処理の流れ−
![]() |
優先的イベントハンドラ |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
SophiaFramework UNIVERSE 内で実際にイベント処理を行う中核的なコード(SFCApplication::Invoke 関数)は以下の通りです。
![]() |
注意 |
---|---|
SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントを受信したとき、 必ず true を返す処理をしていることに注意してください。 |
例 776. SFCApplication クラスにおけるイベントループ
/*private */Bool SFCApplication::Invoke(SFXEventConstRef event) { Bool overload(false); // イベントを重複して処理するかどうかを表すフラグ Bool render(false); // 全画面再描画するかどうかを表すフラグ Bool result(false); // 処理がなされた場合、"true" が設定される switch (event.GetType()) { case SFEVT_APP_START: case SFEVT_APP_RESUME: // SFEVT_APP_START / SFEVT_APP_RESUME の場合 render = true; // 全画面を再描画する case SFEVT_APP_STOP: case SFEVT_APP_SUSPEND: // SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND の場合 overload = true; // イベントを重複して処理する result = true; // BREW の仕様では、これらのイベントには true を返す必要がある break; default: break; } if (_bypass) { // 優先的イベントハンドラが登録されている場合 if (_spp != null) { // 優先的イベントハンドラを呼び出す if ((*_spp)(event, _reference)) { result = true; // イベントを処理した } } } if (render) { // 全画面再描画が必要である場合(アプリ開始時とレジューム時) // 全画面を再描画する if (HandleRender(event)) { result = true; // 全画面を再描画した } } if (!result || overload) { // 優先的イベントハンドラでイベントが処理されなかった、あるいは // SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントの場合 // イベントを処理する if (HandleEvent(event)) { result = true; // イベントを処理した } } return result; }// SFCApplication::Invoke //
■仮想関数
表 203. 仮想関数名とデフォルトの動作
仮想関数名 | デフォルトの動作 | オーバーライド |
---|---|---|
SFCApplication::HandleEvent | - | 任意 |
SFCApplication::HandleRender | 優先的イベントハンドラが登録されていない場合は画面を白色に塗り潰して true 、 そうでない場合は再描画せずに false を返します(※1)。 | 任意 |
SFCApplication::HandleError | − | 任意 |
![]() |
注釈 |
---|---|
※1. メモリ不足などの致命的なエラーが発生した場合は SFCApplication::HandleError 関数を起動します。 |
■ユーザー定義アプリケーションクラスの作成
以下にユーザー定義アプリケーションクラスを作成するときに必要なコードを示します。
例 777. 宣言
SFMTYPEDEFCLASS(USRApplication) class USRApplication : public SFCApplication { SFMSEALCOPY(USRApplication) public: static SFCInvokerPtr Factory(Void); private: explicit USRApplication(Void) static_throws; virtual ~USRApplication(Void); virtual Bool HandleEvent(SFXEventConstRef event); // イベントハンドラ[オプション] virtual Bool HandleRender(SFXEventConstRef event); // 全画面描画ハンドラ[オプション] virtual Bool HandleError(SFXEventConstRef event, SFCError error); // エラーハンドラ[オプション] };
例 778. 実装
// ブートローダ : BREW アプリで最初に実行される関数 SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { // ここにライセンスコードを記述する *license = "heap://"; return (id == AEECLSID_USRAPPLICATION) ? (&USRApplication::Factory) : (null); } // ファクトリ関数 : ユーザー定義アプリケーションクラスのインスタンスを生成する関数 SFCInvokerPtr USRApplication::Factory(Void) { return ::new USRApplication; } // コンストラクタ USRApplication::USRApplication(Void) static_throws { if (static_try()) { // 初期化処理を記述する } } // デストラクタ USRApplication::~USRApplication(Void) { // 終了処理を記述する } // イベントハンドラ[オプション] Bool USRApplication::HandleEvent(SFXEventConstRef event) { Bool result(false); // ここに各種イベントの分岐処理を記述する return result; // イベントを処理した場合は true、そうでない場合は false を返す } // 全画面描画ハンドラ[オプション] Bool USRApplication::HandleRender(SFXEventConstRef event) { // ここにアプリ開始時とレジューム時の全画面の描画処理を記述する SFXGraphicsPtr graphics; Bool result(false); if (IsRenderable()) { // 画面が再描画可能なら(優先的イベントハンドラが登録されていないなら) // SFXGraphics インスタンスを取得する if ((graphics = SFXGraphics::GetInstance()) != null) { // 画面を白色で塗りつぶす // SFXGraphics::GetDeviceRectangle() で画面領域全体を取得する // SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00) は白色を表す( 左から R、G、B、アルファ値 ) graphics->ClearRectangle(graphics->GetDeviceRectangle(), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00)); // ここにその他の全画面再描画処理を記述する // GUI フレームワークを使わないアプリでは必ず画面を更新する graphics->Update(); result = true; // 画面を再描画したので true を設定する } // SFXGraphics インスタンスを取得できなかった場合、HandleError() を呼び出す else if (HandleError(event, SFERR_FAILED)) { result = true; // エラーを処理したので true を設定する } } return result; // 画面を再描画した場合(またはエラー処理した場合)は true、そうでない場合は false を返す } // エラーハンドラ[オプション] Bool USRApplication::HandleError(SFXEventConstRef event, SFCError error) { Bool result(false); // ここに HandleEvent() や HandleRender() で発生した致命的なエラーが発生した場合の処理を記述する return result; // エラーを処理した場合は true、そうでない場合は false を返す }
![]() |
コンストラクタやデストラクタ内の return 文 |
---|---|
C++ ではコンストラクタやデストラクタでは return 文を記述しません。 GCC を使う場合、コンストラクタやデストラクタ内で return 文を記述すると、 特定の継承関係になっているときにコンパイラがフリーズするバグが確認されています。 |
SFYApplication | SFRApplication | SFCApplication::HandleEvent | SFCApplication::HandleRender | SFCApplication::RegisterBypass | SFCApplication::UnregisterBypass | SFCApplication::IsRenderable | BREW API ITextCtl | BREW イベント | SFY レスポンダ | 描画エンジン | 配信エンジン
コンストラクタ/デストラクタ |
---|
SFCApplication( Void ) SFCApplication クラスのコンストラクタです。
|
~SFCApplication( Void ) SFCApplication クラスのデストラクタです。
|
パブリック関数 | |
---|---|
static AEECLSID |
GetClassID( Void ) BREW アプリの ClassID を取得します。
|
static SFCApplicationPtr |
GetInstance( Void ) SFCApplication インスタンスを取得します。
|
Bool |
IsRenderable( Void ) 画面の描画が可能かどうかを判定します。
|
SFCError |
RegisterBypass(
CallbackSPP spp
, VoidPtr reference
) イベントを優先的に処理するためのコールバックを登録します。
|
static SFCError |
Terminate(
Bool idle = false
) アクティブなアプリを終了します。
|
Void |
UnregisterBypass(
CallbackSPP spp
, VoidPtr reference
) 優先的イベントハンドラの登録を解除します。
|
プロテクト関数 | |
---|---|
Bool |
HandleError(
SFXEventConstRef event
, SFCError error
) 致命的なエラーが発生した場合に呼び出される関数です。
|
Bool |
HandleEvent(
SFXEventConstRef event
) アプリが BREW イベントを受信したときに呼び出される関数です(BREW イベントを処理します)。
|
Bool |
HandleRender(
SFXEventConstRef event
) アプリ開始時とレジューム時に呼び出される関数です(全画面を再描画します)。
|
Bool |
Invoke(
SFXEventConstRef event
) BREW イベント受信時に呼び出される仮想関数です。
|
型 |
---|
CallbackSPP 優先的イベントハンドラの型です。
|
[ protected, explicit ] SFCApplication(Void);
このコンストラクタは、 下記の初期化処理を行います。
![]() |
優先的イベントハンドラ |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
このコンストラクタの内部実装は以下の通りです。
class SFCApplication : protected SFCInvoker { ... private: Bool _bypass; ... } /*protected */SFCApplication::SFCApplication(Void) static_throws { if (static_try()) { static_throw(SFCApplet::SetInvoker(this)); if (static_try()) { _bypass = false; } } }// SFCApplication::SFCApplication // /*private static */SFCError SFCApplet::SetInvoker(SFCInvokerPtr param) { SFCAppletPtr iapplet; SFCError error(SFERR_NO_ERROR); if ((iapplet = SFXHelper::getappinstance()) != null) { iapplet->_invoker = param; } else { error = SFERR_FAILED; } return error; }// SFCApplet::SetInvoker // class SFCApplet { SFMSEALCOPY(SFCApplet) public: typedef SFCInvokerPtr (*FactorySPP) (Void); ... private: DECLARE_VTBL(IApplet) AEECLSID _id; UInt32 _telomere; IShell* m_pIShell; IModule* m_pIModule; IDisplay* m_pIDisplay; SFBShellSmp _shell; SFBModuleSmp _module; SFXGraphics _graphics; SFCInvokerPtr _invoker; VoidPtrVolatile _anything; VoidPtr _reserved; VTBL(IApplet) _vtbl; ... }
SFCApplication::Invoke | SFCApplication::~SFCApplication | SFCApplication | SFCApplication::RegisterBypass | イベントループ
[ protected, virtual ] ~SFCApplication(Void);
このデストラクタは、BREW イベントが BREW アプリに通知されても処理されないように SFCApplication::SFCApplication コンストラクタで行った設定をリセットします。
このデストラクタの内部実装は以下の通りです。
/*protected virtual */SFCApplication::~SFCApplication(Void) { SFCApplet::SetInvoker(null); }// SFCApplication::~SFCApplication //
[ public, static ] AEECLSID GetClassID(Void);
![]() |
注意 |
---|---|
BREW アプリの ClassID |
この関数は、BREW アプリの ClassID を取得します。
![]() |
BREW API の GETAPPINSTANCE |
---|---|
この関数は、内部で BREW API GETAPPINSTANCE 関数を呼び出します。 BREW API GETAPPINSTANCE 関数 の戻り値が null の場合、 SFCApplication::GetInstance 関数の戻り値も null となります。 |
この関数の内部実装は以下の通りです。
/*public static */inline AEECLSID SFCApplication::GetClassID(Void) { return SFCApplet::GetClassID(); }// SFCApplication::GetClassID // /*private static */AEECLSID SFCApplet::GetClassID(Void) { SFCAppletConstPtr iapplet; AEECLSID result(UINT32_MINIMUM); if ((iapplet = SFXHelper::getappinstance()) != null) { result = iapplet->_id; } return result; }// SFCApplet::GetClassID //
[ public, static ] SFCApplicationPtr GetInstance(Void);
![]() |
注意 |
---|---|
SFCApplication インスタンス |
この関数は、 SFCApplication インスタンスを取得します。
![]() |
BREW API の GETAPPINSTANCE |
---|---|
この関数は、内部で BREW API GETAPPINSTANCE 関数を呼び出します。 BREW API GETAPPINSTANCE 関数 の戻り値が null の場合、 SFCApplication::GetInstance 関数の戻り値も null となります。 |
この関数の内部実装は以下の通りです。
/*public static */inline SFCApplicationPtr SFCApplication::GetInstance(Void) { return static_cast<SFCApplicationPtr>(SFCApplet::GetInvoker()); }// SFCApplication::GetInstance // /*private static */SFCInvokerPtr SFCApplet::GetInvoker(Void) { SFCAppletPtr iapplet; SFCInvokerPtr result(null); if ((iapplet = SFXHelper::getappinstance()) != null) { result = iapplet->_invoker; } return result; }// SFCApplet::GetInvoker // // 以下は "iapplet->_invoker" がセットされるコードです。 /*protected */SFCApplication::SFCApplication(Void) static_throws { if (static_try()) { static_throw(SFCApplet::SetInvoker(this)); if (static_try()) { _bypass = false; } } }// SFCApplication::SFCApplication // /*private static */SFCError SFCApplet::SetInvoker(SFCInvokerPtr param) { SFCAppletPtr iapplet; SFCError error(SFERR_NO_ERROR); if ((iapplet = SFXHelper::getappinstance()) != null) { iapplet->_invoker = param; } else { error = SFERR_FAILED; } return error; }// SFCApplet::SetInvoker // class SFCApplet { SFMSEALCOPY(SFCApplet) public: typedef SFCInvokerPtr (*FactorySPP) (Void); ... private: DECLARE_VTBL(IApplet) AEECLSID _id; UInt32 _telomere; IShell* m_pIShell; IModule* m_pIModule; IDisplay* m_pIDisplay; SFBShellSmp _shell; SFBModuleSmp _module; SFXGraphics _graphics; SFCInvokerPtr _invoker; VoidPtrVolatile _anything; VoidPtr _reserved; VTBL(IApplet) _vtbl; ... }
[ protected, virtual ] Bool HandleError( SFXEventConstRef event // イベント SFCError error // エラー値 );
この関数は、 配信エンジンや 描画エンジンの起動中に メモリ不足などの致命的なエラーが発生した場合に呼び出される関数です。
エラーを処理した場合は true を返し、 そうでない場合は false を返します。
開発者はこの関数をオーバーライドすることで独自の処理を記述できます。
デフォルトの実装では、false を返す以外何も行いません。
![]() |
注意 |
---|---|
この関数の中でイベントを処理したときには true を そうでないときには false を返します。 けれども、致命的エラーがどこまで正常に実行できるかは未知数です。 一般に、アプリを終了させるなど処理を記述します。 |
この関数の内部実装は以下の通りです。
// 致命的なエラーが発生した場合に呼び出される関数
/*protected virtual */Bool SFCApplication::HandleError(SFXEventConstRef /*event*/, SFCError /*error*/)
{
return false;
}// SFCApplication::HandleError //
[ protected, virtual ] Bool HandleEvent( SFXEventConstRef event // イベント );
この関数は、 アプリが BREW 環境からイベント(BREW イベント) を受信したときに呼び出される仮想関数です(BREW イベントを処理します)。
イベントを処理した場合は true を返し、 そうでない場合は false を返します。
開発者はこの関数をオーバーライドすることで独自の処理を記述できます。
デフォルトの実装では、 false を返す以外何も行いません。
この関数の内部実装は以下の通りです。
// BREW 環境からイベントを受信したときに呼び出される関数: BREW イベントを処理する /*protected virtual */Bool SFCApplication::HandleEvent(SFXEventConstRef /*event*/) { // ここに BREW 環境から受信した各種イベントの分岐処理を記述する return false; }// SFCApplication::HandleEvent //
[ protected, virtual ] Bool HandleRender( SFXEventConstRef event // イベント );
この関数は、 アプリ開始時とレジューム時に呼び出される関数です(全画面を再描画します)。
デフォルトの実装では、 優先的イベントハンドラが登録されていなければ、画面を白色に塗り潰して true を返します。 登録されている場合は、画面の再描画を行わずに false を返します。
開発者はこの関数をオーバーライドすることで独自の処理を記述できます。
![]() |
優先的イベントハンドラについて |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
![]() |
HandleRender 関数が呼び出されるタイミング |
---|---|
この関数は、 SFEVT_APP_START または SFEVT_APP_RESUME イベントを受信した直後に自動的に呼び出されます。 ※ SFCApplication::HandleEvent 関数よりも先に呼び出されることに注意してください (詳細は、SFCApplication クラスの解説にある「SFCApplication クラスにおけるイベントループ」のコードを参照してください)。 |
この関数の内部実装は以下の通りです。
// 全画面の再描画が必要なときに呼び出される仮想関数 /*protected virtual */Bool SFCApplication::HandleRender(SFXEventConstRef event) { // ここにアプリ開始時とレジューム時の全画面の再描画処理を記述する SFXGraphicsPtr graphics; Bool result(false); if (IsRenderable()) { // 画面が再描画可能なら(優先的イベントハンドラが登録されていないなら) // グラフィックスオブジェクトを取得する if ((graphics = SFXGraphics::GetInstance()) != null) { // 画面を白色で塗りつぶす // SFXGraphics::GetDeviceRectangle() で画面領域全体を取得する // SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00) は白色を表す( 左から R、G、B、アルファ値 ) graphics->ClearRectangle(graphics->GetDeviceRectangle(), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00)); // 最後に SFXGraphics::Update() を呼び出して画面を再描画する // ※この一行を記述しなければ、画面は更新されない graphics->Update(); result = true; // 画面を再描画したので true を設定する } // グラフィックスオブジェクトを取得できなかった場合、HandleError() を呼び出す else if (HandleError(event, SFERR_FAILED)) { result = true; } } return result; }// SFCApplication::HandleRender //
参照: SFXGraphics | SFXGraphics::GetInstance | SFXGraphics::GetDeviceRectangle | SFXGraphics::ClearRectangle | SFXGraphics::Update | SFCApplication::IsRenderable | SFCApplication::HandleError | SFYApplication::HandleRender
SFCApplication::IsRenderable | SFCApplication::HandleError | SFCApplication::HandleEvent | アプリ開始時とレジューム時の全画面描画処理
[ protected, virtual ] Bool Invoke( SFXEventConstRef event // イベント );
この関数は、BREW 環境から配信されるイベント(BREW イベント)をアプリが受信したときに最初に呼び出されます。
デフォルトの実装は、以下の「内部実装」にある通りです。
将来的に、この関数は private な関数に変更される予定ですので、 この関数をオーバーライドすることは推奨されません。
BREW イベント受信時の処理のオーバーライドは、 SFCApplication::HandleEvent 関数や SFCApplication::HandleRender 関数で行うことを推奨します。
この関数の内部実装は以下の通りです。
class SFCApplication : protected SFCInvoker { ... private: Bool _bypass; CallbackSPP _spp; VoidPtr _reference; ... } /*private */Bool SFCApplication::Invoke(SFXEventConstRef event) { Bool overload(false); // イベントを重複して処理するかどうかを表すフラグ Bool render(false); // 全画面再描画するかどうかを表すフラグ Bool result(false); // 処理がなされた場合、"true" が設定される switch (event.GetType()) { case SFEVT_APP_START: case SFEVT_APP_RESUME: // SFEVT_APP_START / SFEVT_APP_RESUME の場合 render = true; // 全画面を再描画する case SFEVT_APP_STOP: case SFEVT_APP_SUSPEND: // SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND の場合 overload = true; // イベントを重複して処理する result = true; // BREW の仕様では、これらのイベントには true を返す必要がある break; default: break; } if (_bypass) { // 優先的イベントハンドラが登録されている場合 if (_spp != null) { // 優先的イベントハンドラを呼び出す if ((*_spp)(event, _reference)) { result = true; // イベントを処理した } } } if (render) { // 全画面再描画が必要である場合(アプリ開始時とレジューム時) // 全画面を再描画する if (HandleRender(event)) { result = true; // 全画面を再描画した } } if (!result || overload) { // 優先的イベントハンドラでイベントが処理されなかった、あるいは // SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントの場合 // イベントを処理する if (HandleEvent(event)) { result = true; // イベントを処理した } } return result; }// SFCApplication::Invoke //
SFCApplication::HandleEvent | SFCApplication::HandleRender | SFCApplication::RegisterBypass | SFCApplication::UnregisterBypass | SFCInvoker
[ public, const ] Bool IsRenderable(Void);
ネイティブテキスト入力コントロール( BREW API ITextCtl インターフェース)のように全画面を占有する BREW 標準コントロールを扱うための優先的イベントハンドラが登録されているとき、 全画面はこの優先的イベントハンドラによって占有されます。 このため、優先的イベントハンドラが登録されている間は、これ以外の関数は画面を描画してはいけません。
この関数は、このことを判定するための関数です。
![]() |
優先的イベントハンドラ |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
SFCApplication::HandleRender 関数の実装における使用例です。
// 全画面の再描画が必要なときに呼び出される仮想関数 /*protected virtual */Bool SFCApplication::HandleRender(SFXEventConstRef event) { SFXGraphicsPtr graphics; Bool result(false); if (IsRenderable()) { // 画面が再描画可能なら(優先的イベントハンドラが登録されていないなら) // グラフィックスオブジェクトを取得する if ((graphics = SFXGraphics::GetInstance()) != null) { // 画面を白色で塗りつぶす // SFXGraphics::GetDeviceRectangle() で画面領域全体を取得する // SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00) は白色を表す( 左から R、G、B、アルファ値 ) graphics->ClearRectangle(graphics->GetDeviceRectangle(), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00)); // 最後に SFXGraphics::Update() を呼び出して画面を再描画する // ※この一行を記述しなければ、画面は更新されない graphics->Update(); result = true; // 画面を再描画したので true を設定する } // グラフィックスオブジェクトを取得できなかった場合、HandleError() を呼び出す else if (HandleError(event, SFERR_FAILED)) { result = true; } } return result; }// SFCApplication::HandleRender //
参照: SFXGraphics | SFXGraphics::GetInstance | SFXGraphics::GetDeviceRectangle | SFXGraphics::ClearRectangle | SFXGraphics::Update | SFCApplication::IsRenderable | SFCApplication::HandleError | SFYApplication::HandleRender
この関数の内部実装は以下の通りです。
class SFCApplication : protected SFCInvoker { ... private: Bool _bypass; ... } /*public */Bool SFCApplication::IsRenderable(Void) const { return !_bypass; // SFCApplication::RegisterBypass() でセットされ、SFCApplication::UnregisterBypass() でリセットされる }// SFCApplication::IsRenderable //
SFCApplication::RegisterBypass | SFCApplication::UnregisterBypass | BREW API ITextCtl | BREW イベント | 描画エンジン | 配信エンジン
[ public ] SFCError RegisterBypass( CallbackSPP spp // コールバック関数(優先的イベントハンドラ) VoidPtr reference // コールバック関数(優先的イベントハンドラ)に渡すデータ(参照値) );
この関数は、 優先的イベントハンドラを SFCApplication クラスを継承するアプリケーションクラスのインスタンスに登録するための関数です。
優先的イベントハンドラは、 SFCApplication クラスを継承するアプリケーションクラスのインスタンスにつきひとつだけ登録できます。
![]() |
注意 |
---|---|
SophiaFramework UNIVERSE 5.1.12 から、 SFCApplication::RegisterBypass 関数を使いやすくした SFXEventBypass::Register 関数が利用可能になりました。 SFXEventBypass::Register 関数を利用すれば、 アプリケーションクラスのインスタンス取得を省略できるので、 優先的イベントハンドラの登録には SFXEventBypass::Register 関数を使用します。 |
![]() |
注意 |
---|---|
優先的イベントハンドラは、 SFCApplication クラスを継承するアプリケーションクラスのインスタンスにつきひとつだけ登録できます。 |
![]() |
優先的イベントハンドラ |
---|---|
BREW 環境から通知されたイベントを最初に渡す関数のことを 『優先的イベントハンドラ』と呼びます。 たとえば、 BREW API ITextCtl インターフェースでは、 "アクティブ"であるとき、 BREW 環境から通知されたイベント(BREW イベント)は、 配信エンジンやレスポンダよりも優先して BREW API ITextCtl インターフェースの HandleEvent 関数に渡さなければいけません。 『優先的イベントハンドラ』では、 最初に BREW アプリに通知された BREW イベントを BREW API ITextCtl インターフェースの HandleEvent 関数に渡すコードを記述します。 優先的イベントハンドラは、 SFXEventBypass::Register / SFXEventBypass::Unregister 関数を使用して登録/解除します(※)。 優先的イベントハンドラが登録されている間は、 イベントを優先的に配信する必要のある BREW インターフェースが全画面を占有しますので、 優先的イベントハンドラの登録が解除されたときは全画面の再描画が必要になります (全画面の再描画処理は開発者が記述する必要があります)。 ※1. 優先的イベントハンドラは、BREW アプリ 1 つにつき 1 つまで登録可能です。 ※2. SophiaFramework UNIVERSE 5.1.11 以前は、優先的イベントハンドラは、 SFCApplication::RegisterBypass 関数を使用して登録し、 SFCApplication::UnregisterBypass 関数を使用して解除していました。 |
SFXEditor::Open 関数の実装における使用例です。
------------------------------------------------------------------------------------------------------------ /** *** File : SFXEditor.f.hpp **/ #ifndef __SOPHIAFRAMEWORK_SFXEDITOR_FHPP #define __SOPHIAFRAMEWORK_SFXEDITOR_FHPP #include <SFXGeneral/SFXEnvironment.h.hpp> SFMTYPEDEFCLASS(SFXEditor) #endif // __SOPHIAFRAMEWORK_SFXEDITOR_FHPP // ------------------------------------------------------------------------------------------------------------ /** *** File : SFXEditor.h.hpp **/ #ifndef __SOPHIAFRAMEWORK_SFXEDITOR_HHPP #define __SOPHIAFRAMEWORK_SFXEDITOR_HHPP #include <SFXGeneral/SFXEnvironment.h.hpp> #include <SFXGeneral/SFXBaseEditor.h.hpp> #include <SFXGeneral/SFXEditor.f.hpp> #include <SFXGeneral/SFXEditProperty.f.hpp> #include <SFCCore/SFCApplication.h.hpp> #include <SFBWrapper/SFBTextCtl.h.hpp> class SFXEditor : public SFXBaseEditor { SFMSEALCOPY(SFXEditor) private: SFBTextCtlSmp _textctl; SFBMenuCtlSmp _menuctl; SFXEditPropertyPtr _property; CallbackSPP _spp; VoidPtr _reference; public: explicit SFXEditor (Void); virtual ~SFXEditor (Void); virtual SFCError Open (SFXEditPropertyPtr property, CallbackSPP spp, VoidPtr reference); Void Close (Void); private: XALLBACK_DECLARE_SFCAPPLICATION(OnBypass) }; #include <SFXGeneral/SFXEditor.i.hpp> #endif // __SOPHIAFRAMEWORK_SFXEDITOR_HHPP // ------------------------------------------------------------------------------------------------------------ /** *** File : SFXEditor.i.hpp **/ #ifndef __SOPHIAFRAMEWORK_SFXEDITOR_IHPP #define __SOPHIAFRAMEWORK_SFXEDITOR_IHPP #endif // __SOPHIAFRAMEWORK_SFXEDITOR_IHPP // ------------------------------------------------------------------------------------------------------------ /** *** File : SFXEditor.i.cpp **/ #include <SFXGeneral/SFXEditor.h.hpp> #include <SFXGeneral/SFXDevice.h.hpp> #include <SFXGeneral/SFXEditProperty.h.hpp> #define ITEM_NAME ("Done") #define LABEL_OK 0 /*public */SFXEditor::SFXEditor(Void) : _property(null) { }// SFXEditor::SFXEditor // /*public */SFXEditor::~SFXEditor(Void) { Close(); }// SFXEditor::~SFXEditor // /*public virtual*/SFCError SFXEditor::Open(SFXEditPropertyPtr property, CallbackSPP spp, VoidPtr reference) { #if defined TARGET_ENVIRONMENT_SIMULATOR || defined TARGET_LANGUAGE_ENGLISH static SFXRGBColor::AtomRecConst color[] = { {{{0x00, 0xFF, 0xFF, 0xFF}}}, {{{0x00, 0x00, 0x00, 0x00}}} }; #endif SFBDisplaySmp display; SFXWideString string; SFXRectangle remember; SFXRectangle rectangle; UInt32 flag; SFCError error(SFERR_NO_ERROR); if (property != null) { _property = property; if ((display = SFBDisplay::GetInstance()) != null) { display->GetClipRect(&remember); display->SetClipRect(SFXRectangle::EmptyInstance()); if ((_textctl = SFBTextCtl::NewInstance(GetSFBTextCtlClassID(), &error)) != null) { if ((_menuctl = SFBMenuCtl::NewInstance(GetSFBMenuCtlClassID(), &error)) != null) { if ((error = string.Set(ITEM_NAME)) == SFERR_NO_ERROR) { if (_menuctl->AddItem(LABEL_OK, &string, reinterpret_cast<UInt32>(_menuctl.Get()))) { _textctl->SetSoftKeyMenu(_menuctl); #if defined TARGET_ENVIRONMENT_SIMULATOR || defined TARGET_LANGUAGE_ENGLISH flag = TP_FRAME | TP_MULTILINE | TP_FIXSETRECT; #else flag = TP_NODRAW | TP_FRAME | TP_NOUPDATE | TP_FIXSETRECT; #endif if (_property->GetPasswordMode()) { flag |= TP_PASSWORD; } _textctl->SetProperties(flag); rectangle.Set(SFXGrid::ZeroInstance(), SFXDevice().GetScreenSize()); rectangle.SubBottom(_menuctl->GetRect().GetHeight()); _textctl->SetRect(rectangle); _textctl->SetMaxSize(_property->GetMaximumLength()); _textctl->SetInputMode(_property->GetInputMode()); if (_textctl->SetText(_property->GetText())) { if ((error = RegisterBypass(XALLBACK_INTERNAL(OnBypass))) == SFERR_NO_ERROR) { _spp = spp; _reference = reference; } } else { error = SFERR_FAILED; } } else { error = SFERR_FAILED; } } } } if (error != SFERR_NO_ERROR) { Close(); } display->SetClipRect(remember); if (error == SFERR_NO_ERROR) { #if defined TARGET_ENVIRONMENT_SIMULATOR || defined TARGET_LANGUAGE_ENGLISH display->SetColor(CLR_USER_TEXT, color[1]); display->SetColor(CLR_USER_BACKGROUND, color[0]); display->SetColor(CLR_USER_LINE, color[1]); #endif _textctl->SetActive(true); _textctl->SetCursorPos(TC_CURSORSTART); } } else { error = SFERR_FAILED; } } else { error = SFERR_INVALID_PARAM; } return error; }// SFXEditor::Open // /*public */Void SFXEditor::Close(Void) { if (_textctl != null) { _textctl->SetSoftKeyMenu(SFBMenuCtlSmp::EmptyInstance()); _textctl->SetActive(false); } UnregisterBypass(XALLBACK_INTERNAL(OnBypass)); _textctl.Release(); _menuctl.Release(); _property = null; return; }// SFXEditor::Close // /*private */XALLBACK_IMPLEMENT_SFCAPPLICATION(SFXEditor, OnBypass, event) { SFXWideString string; SFCError error; Bool result(false); result = _textctl->HandleEvent(event); if (!result) { #if defined TARGET_ENVIRONMENT_SIMULATOR result = _menuctl->HandleEvent(event); #endif } switch (event.GetType()) { case SFEVT_APP_RESUME: result = true; break; case SFEVT_APP_SUSPEND: result = true; break; case SFEVT_KEY: case SFEVT_KEY_PRESS: case SFEVT_KEY_RELEASE: #if TARGET_VERSION_LT(3, 0, 0) case SFEVT_KEY_HELD: #endif result = true; break; case SFEVT_COMMAND: if (!result) { switch (event.GetP16()) { case LABEL_OK: if ((error = string.Set(_textctl->GetTextPtr())) == SFERR_NO_ERROR) { if ((error = _property->SetText(string.Substring(0, _property->GetMaximumLength()))) == SFERR_NO_ERROR) { _property->SetInputMode(_textctl->GetInputMode()); } } Close(); if (_spp != null) { (*_spp)(error, _reference); } break; default: break; } result = true; } break; default: break; } return result; }// XALLBACK_IMPLEMENT_SFCAPPLICATION(SFXEditor, OnBypass) //
この関数の内部実装は以下の通りです。
class SFCApplication : protected SFCInvoker { ... private: Bool _bypass; CallbackSPP _spp; VoidPtr _reference; ... } /*public */SFCError SFCApplication::RegisterBypass(CallbackSPP spp, VoidPtr reference) { SFCError error(SFERR_NO_ERROR); if (!_bypass) { _bypass = true; _spp = spp; _reference = reference; } else { error = SFERR_INVALID_STATE; } return error; }// SFCApplication::RegisterBypass //
SFCApplication::UnregisterBypass | SFCApplication::CallbackSPP | SFXEventBypass::Register | SFXEventBypass::Unregister | SFXEditor::Open | SFCApplication::IsRenderable | BREW API ITextCtl | BREW イベント | 描画エンジン | 配信エンジン | SFY レスポンダシステム
この関数は、アクティブなアプリを終了します。
idle 引数に "false"(デフォルト) を指定した場合は、 現在実行中のアプリだけを終了し、BREW アプレットセンター画面に戻ります。
idle 引数に "true" を指定した場合、 全てのアプリを終了し、待ち受け画面に戻ります。 なお、この場合、PL_SYSTEM の特権が必要です、
アプリケーションクラスのインスタンスに割り当てられたメモリは、 ヒープから解放されます。 また、終了対象のアプリには、SFEVT_APP_STOP イベントが送信されます。
この関数は、内部的に BREW API ISHELL_CloseApplet 関数を呼び出します。
![]() |
SFYApplication クラスの終了処理 |
---|---|
SFYApplication クラスの Terminate 関数を呼び出すと、 SFCApplication クラスから継承した SFCApplication::Terminate 関数が実行されます。 このとき、アプリケーションクラスの終了処理が行われ、 デストラクタ(SFYApplication::~SFYApplication 関数)が呼び出されます。 SFYApplication::~SFYApplication 関数では、 ルートを含め レスポンダツリー上にあるすべてのレスポンダの終了処理が行われます。 また、アプリケーションクラスに保持されている 描画エンジンと 配信エンジンの終了処理も行われます。 具体的には、 SFYApplication::~SFYApplication 関数内で、 最初にルートに対して SFXResponderPointer::Release 関数を呼び出してスマートポインタを解放します。 これにより、ルートの参照カウントは "0" となり、 SFYResponder::Terminate 関数が自動的に実行され、終了処理が行われます。 レスポンダツリー上にレスポンダはすべてバラバラに解体され、 これらのレスポンダでも参照カウントが "0" となり、SFYResponder::Terminate 関数が自動的に実行され、 終了処理が行われます。 最後に、SFYRenderer::Terminate 関数と SFYDistributer::Terminate 関数がこの順序で呼び出されて 描画エンジンと配信エンジンの終了処理が行われます。 |
この関数の内部実装は以下の通りです。
/*public static */inline SFCError SFCApplication::Terminate(Bool idle) { return SFCApplet::Terminate(idle); }// SFCApplication::Terminate // /*private static */SFCError SFCApplet::Terminate(Bool idle) { SFCAppletPtr iapplet; SFCError error(SFERR_NO_ERROR); if ((iapplet = SFXHelper::getappinstance()) != null) { error = iapplet->_shell->CloseApplet(idle); } else { error = SFERR_FAILED; } return error; }// SFCApplet::Terminate //
BREW API ISHELL_CloseApplet | SFYApplication | SFYApplication::~SFYApplication | SFXResponderPointer::Release | SFYResponder::Terminate | SFYRenderer::Terminate | SFYDistributer::Terminate | SFY レスポンダ | ルートレスポンダ | レスポンダツリー | 配信エンジン | 描画エンジン
[ public ] Void UnregisterBypass( CallbackSPP spp // 優先的イベントハンドラ VoidPtr reference // 優先的イベントハンドラに渡すデータ(参照値) );
この関数は、 優先的イベントハンドラの登録を解除します。
優先的イベントハンドラは、 SFCApplication クラスを継承するアプリケーションクラスのインスタンスにつきひとつだけ登録できます。
![]() |
優先的イベントハンドラ |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
SFXEditor::Close 関数の実装における使用例です。
/*public */Void SFXEditor::Close(Void)
{
if (_textctl.control != null) {
if (_textctl.control->IsActive()) {
_textctl.control->SetActive(false);
}
}
if (_menuctl.control != null) {
if (_menuctl.control->IsActive()) {
_menuctl.control->SetActive(false);
}
}
if (_application != null) {
_application->UnregisterBypass(XALLBACK_INTERNAL(OnBypass));
}
_textctl.control.Release();
_menuctl.control.Release();
_application = null;
return;
}// SFXEditor::Close //
/*private */XALLBACK_IMPLEMENT_SFCAPPLICATION(SFXEditor, OnBypass, event)
{
SFXWideString string;
SFCError error;
Bool result(false);
...
// SFCApplication::RegisterBypass 関数の使用例にある OnBypass 関数と同じ
....
}// XALLBACK_IMPLEMENT_SFCAPPLICATION(SFXEditor, OnBypass) //
この関数の内部実装は以下の通りです。
class SFCApplication : protected SFCInvoker { ... private: Bool _bypass; CallbackSPP _spp; VoidPtr _reference; ... } /*public */Void SFCApplication::UnregisterBypass(CallbackSPP spp, VoidPtr reference) { if (_bypass) { if (_spp == spp && _reference == reference) { _bypass = false; } } return; }// SFCApplication::UnregisterBypass //
SFCApplication::RegisterBypass | SFCApplication::CallbackSPP | SFXEventBypass::Unregister | SFXEditor::Close | BREW API ITextCtl | BREW イベント | 描画エンジン | 配信エンジン
typedef Bool(* SFCApplication::CallbackSPP)(SFXEventConstRef event, VoidPtr reference)
優先的イベントハンドラの型です。
![]() |
優先的イベントハンドラについて |
---|---|
BREW 環境から通知されたイベントを最初に渡す関数のことを 『優先的イベントハンドラ』と呼びます。 たとえば、 BREW API ITextCtl インターフェースでは、 "アクティブ"であるとき、 BREW 環境から通知されたイベント(BREW イベント)は、 配信エンジンやレスポンダよりも優先して BREW API ITextCtl インターフェースの HandleEvent 関数に渡さなければいけません。 『優先的イベントハンドラ』では、 最初に BREW アプリに通知された BREW イベントを BREW API ITextCtl インターフェースの HandleEvent 関数に渡すコードを記述します。 優先的イベントハンドラは、 SFXEventBypass::Register / SFXEventBypass::Unregister 関数を使用して登録/解除します(※)。 優先的イベントハンドラが登録されている間は、 イベントを優先的に配信する必要のある BREW インターフェースが全画面を占有しますので、 優先的イベントハンドラの登録が解除されたときは全画面の再描画が必要になります (全画面の再描画処理は開発者が記述する必要があります)。 ※1. 優先的イベントハンドラは、BREW アプリ 1 つにつき 1 つまで登録可能です。 ※2. SophiaFramework UNIVERSE 5.1.11 以前は、優先的イベントハンドラは、 SFCApplication::RegisterBypass 関数を使用して登録し、 SFCApplication::UnregisterBypass 関数を使用して解除していました。 |
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |
![]() ![]() ![]() ![]() |