前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.2
SFCApplication
アプリケーションの基底クラスです。
#include <SFCApplication.h.hpp>
class SFCApplication : public SFCInvoker;
SFMTYPEDEFCLASS(SFCApplication)

継承図

SFCApplication クラスの継承図

協調図

SFCApplication クラスの協調図

解説

■ 仕様と使い方

すべてのアプリケーションクラスは SFCApplication クラスを継承します。

[Note] 注意

SFCApplication クラスを直接継承したアプリケーションクラスを使用する場合、 必要な初期設定を行わない限り SFY レスポンダシステムを利用できません。

通常、SFY レスポンダシステムを利用するには、 必要な初期設定が予め実装されている SFYApplication クラスを継承してアプリケーションクラスを作成します。

詳しくは ルートの解説を参照してください。

■イベント処理 −全体的な処理の流れ−

  1. 登録されていれば、最初に優先的イベントハンドラを呼び出して BREW 環境から受信したイベント(BREW イベント)を優先的に処理します。
  2. SFEVT_APP_START / SFEVT_APP_RESUME イベントを受信したとき、 HandleRender 関数を呼び出して全画面を再描画します。
  3. SFEVT_APP_START / SFEVT_APP_RESUME / SFEVT_APP_STOP / SFEVT_APP_SUSPEND イベントを受信したとき、 あるいは、優先的イベントハンドラがイベントを処理しなかったとき、 HandleEvent 関数を呼び出してイベント処理を行います。
  4. メモリ不足などの致命的エラーが発生したときは、HandleError 関数を呼び出してエラー処理を行います。 デフォルトでは、この関数は SFCApplication::HandleRender 関数の内部から呼び出されます。
[Note] 優先的イベントハンドラ

SFCApplication::RegisterBypass にある解説を参照してください。

SophiaFramework UNIVERSE 内で実際にイベント処理を行う中核的なコード(SFCApplication::Invoke 関数)は以下の通りです。

[Note] 注意

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 任意
[Note] 注釈

※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 を返す
}
[Caution] コンストラクタやデストラクタ内の 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
優先的イベントハンドラの型です。

SFCApplication::SFCApplication
SFCApplication クラスのコンストラクタです。
[ protected, explicit ]
SFCApplication(Void);

解説

このコンストラクタは、 下記の初期化処理を行います。

  1. BREW イベントが BREW アプリに通知されたとき、 最初にそのイベントを SFCApplication::Invoke 関数に通知する設定を行います。 イベントループは、この関数の呼び出しから始まります。 (参考情報: SFCApplication の解説にある『■イベント処理[全体的な処理の流れ]』)
  2. 優先的イベントハンドラが登録されていない状態に設定します。
[Note] 優先的イベントハンドラ

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 | イベントループ


SFCApplication::~SFCApplication
SFCApplication クラスのデストラクタです。
[ protected, virtual ]
~SFCApplication(Void);

解説

このデストラクタは、BREW イベントが BREW アプリに通知されても処理されないように SFCApplication::SFCApplication コンストラクタで行った設定をリセットします。

内部実装

このデストラクタの内部実装は以下の通りです。

/*protected virtual */SFCApplication::~SFCApplication(Void)
{
    SFCApplet::SetInvoker(null);
}// SFCApplication::~SFCApplication //


参照

SFCApplication::SFCApplication | SFCApplication


SFCApplication::GetClassID
BREW アプリの ClassID を取得します。
[ public, static ]
AEECLSID GetClassID(Void);

戻り値

[Note] 注意

BREW アプリの ClassID

解説

この関数は、BREW アプリの ClassID を取得します。

[Note] 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 //

SFCApplication::GetInstance
SFCApplication インスタンスを取得します。
[ public, static ]
SFCApplicationPtr GetInstance(Void);

戻り値

[Note] 注意

SFCApplication インスタンス

解説

この関数は、 SFCApplication インスタンスを取得します。

[Note] 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;
    ...

}

参照

BREW API GETAPPINSTANCE


SFCApplication::HandleError
致命的なエラーが発生した場合に呼び出される関数です。
[ protected, virtual ]
Bool HandleError(
    SFXEventConstRef event   // イベント
    SFCError error           // エラー値
);

戻り値

  • イベントを処理したとき: true
  • そうでないとき: false[デフォルト]

解説

この関数は、 配信エンジン描画エンジンの起動中に メモリ不足などの致命的なエラーが発生した場合に呼び出される関数です。

エラーを処理した場合は true を返し、 そうでない場合は false を返します。

開発者はこの関数をオーバーライドすることで独自の処理を記述できます。

デフォルトの実装では、false を返す以外何も行いません。

[Note] 注意

この関数の中でイベントを処理したときには true を そうでないときには false を返します。 けれども、致命的エラーがどこまで正常に実行できるかは未知数です。

一般に、アプリを終了させるなど処理を記述します。

内部実装

この関数の内部実装は以下の通りです。

// 致命的なエラーが発生した場合に呼び出される関数
/*protected virtual */Bool SFCApplication::HandleError(SFXEventConstRef /*event*/, SFCError /*error*/)
{
    return false;

}// SFCApplication::HandleError //

参照

SFCApplication::HandleEvent | SFCApplication::HandleRender | 描画エンジン | 配信エンジン


SFCApplication::HandleEvent
アプリが BREW イベントを受信したときに呼び出される関数です(BREW イベントを処理します)。
[ protected, virtual ]
Bool HandleEvent(
    SFXEventConstRef event   // イベント
);

戻り値

  • イベントを処理したとき: true
  • そうでないとき: false[デフォルト]

解説

この関数は、 アプリが BREW 環境からイベント(BREW イベント) を受信したときに呼び出される仮想関数です(BREW イベントを処理します)。

イベントを処理した場合は true を返し、 そうでない場合は false を返します。

開発者はこの関数をオーバーライドすることで独自の処理を記述できます。

デフォルトの実装では、 false を返す以外何も行いません。

内部実装

この関数の内部実装は以下の通りです。

// BREW 環境からイベントを受信したときに呼び出される関数: BREW イベントを処理する
/*protected virtual */Bool SFCApplication::HandleEvent(SFXEventConstRef /*event*/)
{
    // ここに BREW 環境から受信した各種イベントの分岐処理を記述する

    return false;

}// SFCApplication::HandleEvent //

参照

イベント処理 | BREW イベント


SFCApplication::HandleRender
アプリ開始時とレジューム時に呼び出される関数です(全画面を再描画します)。
[ protected, virtual ]
Bool HandleRender(
    SFXEventConstRef event   // イベント
);

戻り値

  • 全画面を再描画したとき: true
  • そうでないとき: false

解説

この関数は、 アプリ開始時とレジューム時に呼び出される関数です(全画面を再描画します)。

デフォルトの実装では、 優先的イベントハンドラが登録されていなければ、画面を白色に塗り潰して true を返します。 登録されている場合は、画面の再描画を行わずに false を返します。

開発者はこの関数をオーバーライドすることで独自の処理を記述できます。

[Note] 優先的イベントハンドラについて

SFCApplication::RegisterBypass にある解説を参照してください。

[Note] 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 | アプリ開始時とレジューム時の全画面描画処理


SFCApplication::Invoke
BREW イベント受信時に呼び出される仮想関数です。
[ protected, virtual ]
Bool Invoke(
    SFXEventConstRef event   // イベント
);

戻り値

  • イベントを処理したとき: true
  • そうでないとき: false

解説

この関数は、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


SFCApplication::IsRenderable
画面の描画が可能かどうかを判定します。
[ public, const ]
Bool IsRenderable(Void);

戻り値

  • 画面を描画できるとき: true
  • そうできないとき: false

解説

ネイティブテキスト入力コントロール( BREW API ITextCtl インターフェース)のように全画面を占有する BREW 標準コントロールを扱うための優先的イベントハンドラが登録されているとき、 全画面はこの優先的イベントハンドラによって占有されます。 このため、優先的イベントハンドラが登録されている間は、これ以外の関数は画面を描画してはいけません。

この関数は、このことを判定するための関数です。

[Note] 優先的イベントハンドラ

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 イベント | 描画エンジン | 配信エンジン


SFCApplication::RegisterBypass
イベントを優先的に処理するためのコールバックを登録します。
[ public ]
SFCError RegisterBypass(
    CallbackSPP spp     // コールバック関数(優先的イベントハンドラ)
    VoidPtr reference   // コールバック関数(優先的イベントハンドラ)に渡すデータ(参照値)
);

戻り値

  • 成功したとき: SFERR_NO_ERROR
  • spp 引数が null とき: SFERR_INVALID_PARAM
  • 優先的イベントハンドラが登録済みのとき: SFERR_INVALID_STATE

解説

この関数は、 優先的イベントハンドラを SFCApplication クラスを継承するアプリケーションクラスのインスタンスに登録するための関数です。

優先的イベントハンドラは、 SFCApplication クラスを継承するアプリケーションクラスのインスタンスにつきひとつだけ登録できます。

[Note] 注意

SophiaFramework UNIVERSE 5.1.12 から、 SFCApplication::RegisterBypass 関数を使いやすくした SFXEventBypass::Register 関数が利用可能になりました。

SFXEventBypass::Register 関数を利用すれば、 アプリケーションクラスのインスタンス取得を省略できるので、 優先的イベントハンドラの登録には SFXEventBypass::Register 関数を使用します。

[Caution] 注意

優先的イベントハンドラは、 SFCApplication クラスを継承するアプリケーションクラスのインスタンスにつきひとつだけ登録できます。

[Note] 優先的イベントハンドラ

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 レスポンダシステム


SFCApplication::Terminate
アクティブなアプリを終了します。
[ public, static ]
SFCError Terminate(
    Bool idle = false   // 全てのアプリを終了するかどうか(実機でのみ有効)
);

戻り値

  • 成功したとき: SFERR_NO_ERROR
  • 失敗したとき: SFERR_FAILED
  • idle 引数に true を指定したときに PL_SYSTEM の特権を有していなかったとき: EPRIVLEVEL

解説

この関数は、アクティブなアプリを終了します。

idle 引数に "false"(デフォルト) を指定した場合は、 現在実行中のアプリだけを終了し、BREW アプレットセンター画面に戻ります。

idle 引数に "true" を指定した場合、 全てのアプリを終了し、待ち受け画面に戻ります。 なお、この場合、PL_SYSTEM の特権が必要です、

アプリケーションクラスのインスタンスに割り当てられたメモリは、 ヒープから解放されます。 また、終了対象のアプリには、SFEVT_APP_STOP イベントが送信されます。

この関数は、内部的に BREW API ISHELL_CloseApplet 関数を呼び出します。

[Note] 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 レスポンダ | ルートレスポンダ | レスポンダツリー | 配信エンジン | 描画エンジン


SFCApplication::UnregisterBypass
優先的イベントハンドラの登録を解除します。
[ public ]
Void UnregisterBypass(
    CallbackSPP spp     // 優先的イベントハンドラ
    VoidPtr reference   // 優先的イベントハンドラに渡すデータ(参照値)
);

解説

この関数は、 優先的イベントハンドラの登録を解除します。

優先的イベントハンドラは、 SFCApplication クラスを継承するアプリケーションクラスのインスタンスにつきひとつだけ登録できます。

[Note] 優先的イベントハンドラ

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 イベント | 描画エンジン | 配信エンジン


SFCApplication::CallbackSPP
優先的イベントハンドラの型です。
typedef Bool(* SFCApplication::CallbackSPP)(SFXEventConstRef event, VoidPtr reference)

解説

優先的イベントハンドラの型です。

[Note] 優先的イベントハンドラについて

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 関数を使用して解除していました。

参照

SFXEventBypass::Register | SFXEventBypass::Unregister | SFCApplication::RegisterBypass | SFCApplication::UnregisterBypass | UI を表示する BREW インターフェース