SophiaFramework UNIVERSE 5.3 |
#include <SFCApplication.h.hpp>
class SFCApplication : public SFCInvoker;
SFMTYPEDEFCLASS(SFCApplication)
■ 仕様と使い方
すべてのアプリケーションクラスは SFCApplication クラスを継承します。
注意 | |
---|---|
SFCApplication クラスを直接継承したアプリケーションクラスを使用する場合、 必要な初期設定を行わない限り SFY レスポンダシステムを利用できません。 通常、SFY レスポンダシステムを利用するには、 必要な初期設定が予め実装されている SFYApplication クラスを継承してアプリケーションクラスを作成します。 詳しくは ルートの解説を参照してください。 |
■□■ SFC アプリの全体的な処理の流れ ■□■
□ アプリの起動
SFC アプリの起動は、 SFY アプリと同様にブートローダ (SFCApplet::Boot 関数)によって行います。
注意 | |
---|---|
SFCApplet::Boot 関数はアプリで最初に実行される関数です。 |
ブートローダーにより、 ファクトリ関数(helloworld::Factory 関数)が実行され、 アプリケーションクラスのインスタンスが作成されます。
これ以降、SFCApplication::Terminate 関数の呼び出し、 または電源キー(AVK_POWER)/クリアキー(AVK_CLR)の押下などによりアプリが終了するまで、 アプリは実行中であり、必要に応じて BREW イベントを処理します。
ブートローダ(SFCApplet::Boot 関数)とファクトリ関数(helloworld::Factory 関数)は、 以下のように実装します。
ブートローダ(SFCApplet::Boot 関数)には、ライセンスコードを設定し、 引数 id が AEECLSID_HELLOWORLD であるときに helloworld アプリケーションクラスのインスタンスファクトリ関数 (helloworld::Factory 関数)を返す処理を記述します。
ファクトリ関数(helloworld::Factory 関数)には、 helloworld アプリケーションクラスのインスタンスを生成する処理を記述します。
Tip | |
---|---|
アプリケーションクラスのインスタンスは、 1 アプリにつき 1 つだけ生成します。 |
ClassID とライセンスコード | |
---|---|
BREW 実機(BREW 移動機)では、 アプリの ClassID に対応した正規ライセンスコードを設定しなければアプリは起動しません。 開発時は Example / Tutorial フォルダ内にあるサンプルアプリの ClassID とライセンスコードをテスト用に使用してください BREW シミュレータでは、ライセンスコードを設定しなくてもアプリは起動します。 参照: ライセンスコード |
例 780. ブートローダとファクトリ関数
//// helloworld.cpp // #include "helloworld.hpp" // ブートローダ SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { // 実行ライセンスコードを設定する(実機の場合は必須。シミュレーターでは省略可) *license = "heap://" "TIXDRQXNU5WHU8Y3Z9WOHWQR6Z3VPSDHDV5CR1S4XASPWLUHWAS7Z5Z2TGS3XMSAT3UPUQTLTARCYPSF" "UEJZ6ROSJWGUQSEYKR6V2U4VESMTQLHKZ6X7Y2VKXHWIX3XBU0Z7VHWHXIZBSGT5SPU3XLX0Z1Y4R3TC" "U6WGT9WHWIVNYHYCUCR9T3SMTEWPRNVAX1Y4VPW2YCY9YQV5R7Z9UIVHT6SDUPU2SIW6VCRCWBR2S4WQ" "UPYFWCYGT4VIT1WHXGYPTQSFYPWNV3ULRNWFW7RBRFVKUKS2YQSQYHW1TPUPXBZ6UEY2WOYKR7S3TAU4" "TQS6UHVFVEVLU3R5SDSKW7RPTNTPVQU2T4R8Z4VLUGEW3U98TLDR8/"; return (id == AEECLSID_HELLOWORLD) ? (&helloworld::Factory) : (null); } // ファクトリ関数 SFCInvokerPtr helloworld::Factory(Void) { return ::new helloworld; // helloworld アプリケーションクラスのインスタンスを生成する }
□ イベントループ
SFC アプリでは、 アプリ起動後(アプリケーションクラスのインスタンス生成後)、 BREW 環境からイベント(BREW イベント)を受信すると、 SFCApplication::Invoke 関数が呼び出されて以下の処理を行います (参照: SFCApplication::Invoke 関数の内部実装)。
優先的イベントハンドラについて | |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
例 781. SFCApplication::Invoke 関数の内部実装
/*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 != null) { // 優先的イベントハンドラの処理 // 優先的イベントハンドラを呼び出す result = (*_bypass)(event, _reference); } if (render) { // アプリ開始/再開時と優先的イベントハンドラ終了時の全画面再描画 if (IsRenderable()) { // 優先的イベントハンドラが登録されていない場合 // 全画面を再描画する HandleRender(event); } } if (!result || overload) { // 優先的イベントハンドラで処理されなかったイベント、あるいは // SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントの処理 // イベントを処理する result = HandleEvent(event) || overload; } return result; }// SFCApplication::Invoke //
注意 | |
---|---|
SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントを受信したとき、 必ず true を返す処理をしていることに注意してください。 |
SFCApplication::HandleRender / SFCApplication::HandleEvent / SFCApplication::HandleError 仮想関数のデフォルトの実装は、各関数の内部実装コードを参照してください。
これらの仮想関数は、アプリの処理内容に応じてユーザー定義アプリケーションクラスにて上書き実装します。
□ アプリの終了
アプリを終了するには、 SFCApplication::Terminate 関数を呼び出します。
SFCApplication::Terminate 関数を呼び出すと、 内部的に BREW API ISHELL_CloseApplet 関数が呼び出されます。 そのとき、アプリは SFEVT_APP_STOP イベントを受信し、 アプリケーションクラスのデストラクタを実行した後アプリケーションクラスのインスタンスは解放され、 アプリは終了します。
SFCApplication::~SFCApplication デストラクタは、 アプリが BREW イベントを処理しない設定にします。
利用者が電源キー(AVK_POWER)を押下した場合、 もしくはクリアキー(AVK_CLR)を押下時にアプリが AEE に false を返した場合、 SFCApplication::Terminate 関数呼び出しと同等の処理が自動的に行われてアプリは終了します。
注意 | |
---|---|
クリアキー(AVK_CLR)の SFEVT_KEY イベントはアプリ側で処理できますが、 電源キー(AVK_POWER)はアプリ側では処理できません。 |
■仮想関数
表 203. 仮想関数名とデフォルトの動作
仮想関数名 | デフォルトの動作 | オーバーライド |
---|---|---|
SFCApplication::HandleEvent | - | 任意 |
SFCApplication::HandleRender | 画面を白色に塗り潰します(※1)。 | 任意 |
SFCApplication::HandleError | − | 任意 |
注釈 | |
---|---|
※1. メモリ不足などの致命的なエラーが発生した場合は SFCApplication::HandleError 関数を起動します。 |
■ユーザー定義アプリケーションクラスの作成
以下にユーザー定義アプリケーションクラスを作成するときに必要なコードを示します。
例 782. 宣言
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); // エラーハンドラ[オプション] };
例 783. 実装
// ブートローダ : 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) { static SFXRGBColor::AtomRecConst theme = { {{0x00, 0xFF, 0xFF, 0xFF}} // 白色 }; SFXGraphicsPtr graphics; Bool result(false); // SFXGraphics インスタンスを取得する if ((graphics = SFXGraphics::GetInstance()) != null) { // デバイス画面領域を白色で塗りつぶす graphics->ClearRectangle(SFXGraphics::GetDeviceRectangle(), theme); // ここにその他のデバイス画面の再描画を記述する ... // デバイス画面を更新する graphics->Update(); result = true; } else { HandleError(event, SFERR_FAILED); } return result; } // エラーハンドラ[オプション] 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 |
IsHandlingEvent( Void ) イベント処理中かどうかを判定します。
|
Bool |
IsRenderable( Void ) 画面の描画が可能かどうかを判定します。
|
SFCError |
RegisterBypass(
CallbackSPP spp
, VoidPtr reference
) イベントを優先的に処理するためのコールバックを登録します。
|
Bool |
RenderDeviceScreen( Void ) デバイス画面を再描画します。
|
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 // イベント );
この関数は、 アプリ開始/再開時と優先的イベントハンドラ終了時に呼び出される関数です(全画面を再描画します)。
優先的イベントハンドラが実行中の場合、この関数は呼び出されません。
全画面(デバイス画面)の再描画を行います。
デフォルトの実装は、全画面(デバイス画面)を白色に塗り潰します。
開発者はこの関数をオーバーライドすることで独自の処理を記述できます。
優先的イベントハンドラについて | |
---|---|
SFCApplication::RegisterBypass にある解説を参照してください。 |
HandleRender 関数が呼び出されるタイミング | |
---|---|
アプリ開始/再開時と優先的イベントハンドラ終了時は、 全画面の再描画が必要になります。 HandleRender 関数は、これらのタイミングで呼び出されます。 アプリ開始/再開時は SFCApplication::Invoke 関数内から、 優先的イベントハンドラ終了時は SFCApplication::RenderDeviceScreen 関数内から自動的に呼び出されます。 HandleEvent 関数よりも先に呼び出されることに注意してください ※ 詳細は、SFCApplication クラスの解説にある 「SFC アプリの全体的な処理の流れ」のコードを参照してください。 |
この関数の内部実装は以下の通りです。
// アプリ開始/再開時と優先的イベントハンドラ終了時に呼び出される仮想関数 /*protected virtual */Bool SFCApplication::HandleRender(SFXEventConstRef event) { static SFXRGBColor::AtomRecConst theme = { {{0x00, 0xFF, 0xFF, 0xFF}} // 白色 }; SFXGraphicsPtr graphics; Bool result(false); // SFXGraphics インスタンスを取得する if ((graphics = SFXGraphics::GetInstance()) != null) { // デバイス画面領域を白色で塗りつぶす graphics->ClearRectangle(SFXGraphics::GetDeviceRectangle(), theme); // デバイス画面を更新する graphics->Update(); result = true; } else { HandleError(event, SFERR_FAILED); } return result; }// SFCApplication::HandleRender //
参照: SFXGraphics | SFXGraphics::GetInstance | SFXGraphics::GetDeviceRectangle | SFXGraphics::ClearRectangle | SFXGraphics::Update | SFCApplication::HandleError
SFCApplication::HandleError | SFCApplication::HandleEvent | SFCApplication::RenderDeviceScreen | アプリ開始/再開時と優先的イベントハンドラ終了時の全画面再描画
[ 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 != null) { // 優先的イベントハンドラの処理 // 優先的イベントハンドラを呼び出す result = (*_bypass)(event, _reference); } if (render) { // アプリ開始/再開時と優先的イベントハンドラ終了時の全画面再描画 if (IsRenderable()) { // 優先的イベントハンドラが登録されていない場合 // 全画面を再描画する HandleRender(event); } } if (!result || overload) { // 優先的イベントハンドラで処理されなかったイベント、あるいは // SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントの処理 // イベントを処理する result = HandleEvent(event) || overload; } return result; }// SFCApplication::Invoke //
SFCApplication::HandleEvent | SFCApplication::HandleRender | SFCApplication::RegisterBypass | SFCApplication::UnregisterBypass | SFCInvoker
[ public, const ] Bool IsHandlingEvent(Void);
現在、イベント処理ループ (SFCApplication::Invoke 関数) の中にいるかどうかを判定します。
[ 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(SFXGraphics::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
この関数の内部実装は以下の通りです。
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); } if ((application = SFCApplication::GetInstance()) != null) { application->RenderDeviceScreen(); } 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 | BREW API ITextCtl | BREW イベント | 描画エンジン | 配信エンジン | SFY レスポンダシステム
[ public ] Bool RenderDeviceScreen(Void);
この関数は、 内部的に SFCApplication::HandleRender / SFYApplication::HandleRender 関数を呼び出してデバイス画面を再描画します。
アプリ開始/再開以外の時、 主に優先的イベントハンドラが解除された直後、 デバイス画面を明示的に再描画する必要があるときにこの関数を呼び出します。
注意 | |
---|---|
SFC アプリの場合は SFCApplication::HandleRender 関数が呼び出され、 SFY アプリの場合は SFYApplication::HandleRender 関数が呼び出されます。 |
優先的イベントハンドラについて | |
---|---|
SFXEventBypass クラスの解説を参照してください。 |
この関数の内部実装は以下の通りです。
/*public */Bool SFCApplication::RenderDeviceScreen(Void) { return HandleRender(SFXEvent(0, 0, 0)); }// SFCApplication::RenderDeviceScreen //
SFXEditor クラスなど優先的イベントハンドラを用いるクラスで使用されています。
/*private */XALLBACK_IMPLEMENT_SFCAPPLICATION(SFXEditor, OnBypass, event) { SFXWideString string; SFCApplicationPtr application; SFCError error; Bool result(false); result = _textctl->HandleEvent(event); #if defined TARGET_ENVIRONMENT_SIMULATOR || defined TARGET_LANGUAGE_ENGLISH if (!result) { result = _menuctl->HandleEvent(event); } #endif switch (event.GetType()) { // ... (省略) ... 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)) == SFERR_NO_ERROR) { _property->SetInputMode(_textctl->GetInputMode()); } } Close(); // 優先的イベントハンドラの復帰コールバック呼び出し if (_spp != null) { (*_spp)(error, _reference); } // 全画面を再描画する if ((application = SFCApplication::GetInstance()) != null) { application->RenderDeviceScreen(); } break; default: break; } result = true; } break; default: break; } return result; }// XALLBACK_IMPLEMENT_SFCAPPLICATION(SFXEditor, OnBypass) //
この関数は、アクティブなアプリを終了します。
idle 引数に "false"(デフォルト) を指定した場合は、 現在実行中のアプリだけを終了し、BREW アプレットセンター画面に戻ります。
idle 引数に "true" を指定した場合、 全てのアプリを終了し、待ち受け画面に戻ります(この場合、PL_SYSTEM の特権が必要です)。
この関数は、内部的に BREW API ISHELL_CloseApplet 関数を呼び出します。
終了対象のアプリには、SFEVT_APP_STOP イベントが送信されます。 SFEVT_APP_STOP イベントの処理終了後、 アプリケーションクラスのデストラクタが呼び出され、 アプリケーションクラスのインスタンスに割り当てられたメモリはヒープから解放されます。
SFYApplication クラスの終了処理 | |
---|---|
SFYApplication クラスの Terminate 関数を呼び出すと、 SFCApplication::Terminate 関数が実行されます。 このとき、 内部的に BREW API ISHELL_CloseApplet 関数を呼び出され、 SFEVT_APP_STOP イベントが終了対象のアプリ送信されます。 その後、 アプリケーションクラスの終了処理が行われ、 SFYApplication::~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 インターフェースが全画面を占有します。 そのため、優先的イベントハンドラの登録が解除された直後、 SFCApplication::RenderDeviceScreen 関数を呼び出して 全画面を再描画し、アプリの画面を復元する必要があります。 ※1. 優先的イベントハンドラは、BREW アプリ 1 つにつき 1 つまで登録可能です。 ※2. SophiaFramework UNIVERSE 5.1.11 以前は、優先的イベントハンドラは、 SFCApplication::RegisterBypass 関数を使用して登録し、 SFCApplication::UnregisterBypass 関数を使用して解除していました。 |
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |