前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

9.7. アプリケーションクラス(基礎編)

レスポンダシステムを利用するすべての BREW アプリは SFYApplication クラスを継承し、 ユーザー定義アプリケーションクラスを実装する必要があります。

SFYApplication はレスポンダではありませんが、 デフォルトで配信エンジン描画エンジンが関連付けられたルートSFZRoot)を保持します。

SFYApplication に対するレスポンダ関連の操作はデフォルトのルートSFZRoot)に委譲されます。 SFYApplication に用意された API の範囲内でアプリケーションクラスはレスポンダのように振舞います。

表 9.5. 抽象アプリケーションクラスの種類

クラス名 解説
SFYApplication アプリケーションクラスを表す抽象クラスです。

9.7.1. アプリケーションクラスを表す抽象クラス[SFYApplication]

SFYApplication は、各種アプリケーションクラスを実装するための起点(基底クラス)となります。

このクラスは、デフォルトで配信エンジン描画エンジンが関連付けられたルートを保持します。 また、以下の仮想関数のデフォルトの動作を実装します。

表 9.6. 仮想関数名とデフォルトの動作

仮想関数名 デフォルトの動作 オーバーライド
SFYApplication::HandleEvent イベントを配信し、ルート以下のレスポンダツリーを再描画する※1 任意
SFYApplication::HandleRender 全画面(デバイス画面とルート以下のレスポンダツリー)を再描画する※1 任意
SFCApplication::HandleError - 任意
[Note] 注釈

※1. メモリ不足などの致命的なエラーが発生した場合は SFCApplication::HandleError 関数を起動します。

ユーザー定義アプリケーションクラスを作成するときに最低限必要なコードを示します。

例 9.38. 宣言

SFMTYPEDEFCLASS(USRApplication)
class USRApplication: public SFYApplication {
    SFMSEALCOPY(USRApplication)
public:
    static SFCInvokerPtr Factory(Void);
private:
    explicit USRApplication(Void) static_throws;
    virtual ~USRApplication(Void);
};

例 9.39. 実装

// ブートローダ: 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)
{
    // 終了処理を記述する
}
[Caution] コンストラクタやデストラクタ内の return 文

C++ ではコンストラクタやデストラクタでは return 文を記述しません。

GCC を使う場合、コンストラクタやデストラクタ内で return 文を記述すると、 特定の継承関係になっているときにコンパイラがフリーズするバグが確認されています。

SFYApplication::HandleEvent 仮想関数の実装は以下の通りです。

例 9.40. 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 (event.GetType() != SFEVT_APP_STOP & event.GetType() != SFEVT_APP_SUSPEND)) {  
            // 再描画が必要な場合

            if (IsRenderable()) {  // 優先的イベントハンドラが登録されていない場合

                // 描画エンジンを起動してルート以下のレスポンダツリーを再描画する
                error = _root->Render();
            }
        }
    }
    if (error != SFERR_NO_ERROR) {
        // 配信エンジンや描画エンジンの起動時にメモリ不足などの致命的エラーが発生した場合

        if (HandleError(event, error)) {

            result = true;
        }
    }
    if ((event.GetType() == SFEVT_APP_SUSPEND) & IsRendererIntermissive()) {
        // サスペンド時に描画エンジン内部のデバイス画面保存用ビットマップを解放する場合

        // 描画エンジンを終了する
        _renderer.Terminate();
    }
    return result; // イベントを処理したときは true を返し, そうでないときは false を返す
}// SFYApplication::HandleEvent //

参照: SFCApplication::HandleEvent | SFCApplication::IsRenderable | SFCApplication::HandleError | SFYApplication::IsRendererIntermissive | SFYResponder::Distribute | SFYResponder::Render | SFYRenderer::Initialize | SFYRenderer::Terminate | SFZRoot | ルート | トレーサ | 配信エンジン | 描画エンジン | 描画イベント | 描画ハンドラ | イベントループ | 可視領域 | 再描画領域

SFYApplication::HandleRender 仮想関数の実装は以下の通りです。

例 9.41. SFYApplication::HandleRender 関数の実装

// アプリ開始/再開時と優先的イベントハンドラ終了時に呼び出される仮想関数
/*protected virtual */Bool SFYApplication::HandleRender(SFXEventConstRef event)
{
    // ここに全画面(デバイス画面とルート以下のレスポンダツリー)の再描画を記述する
    SFCError  error;
    Bool      result(false);

    if (SFCApplication::HandleRender(event)) { // デバイス画面を再描画する

        // ルート以下のレスポンダツリーを再描画する
        // ※1. 可能であれば、デバイス画面保存用ビットマップを利用して高速に再描画行う
        // ※2. SFEVT_APP_START 受信時などデバイス画面保存用ビットマップが利用不可の場合は引数に true を指定して Render 関数を呼び出す(強制再描画を行う)
        error = _root->Render((event.GetType() == SFEVT_APP_START) || (_root->Recover() != SFERR_NO_ERROR));

        if (error == SFERR_NO_ERROR) {

            result = true;
        }
        else {
            // 描画エンジンの起動時にメモリ不足などの致命的エラーが発生した場合、HandleError() を呼び出す
            HandleError(event, error);
        }
    }
    return result;
}// SFYApplication::HandleRender //

参照: SFCApplication::HandleRender | SFCApplication::HandleError | SFCApplication::RenderDeviceScreen | SFYResponder::Render | SFYResponder::Recover | SFZRoot | ルート | 描画エンジン