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

5.2. SFR アプリ

SFR アプリとは、SFRApplication クラスを継承して SFR GUI フレームワークを使うアプリのことです。

ここでは、SophiaFramework UNIVERSE AppWizard が自動生成した HelloWorld アプリのコードを使用して、SFR アプリの起動から終了までの処理の流れを解説します。

5.2.1. アプリの起動

SFR アプリは、ブートローダと呼ぶ SFCApplet::Boot 関数と Factory 関数を実装する必要があります。

SFCApplet::Boot 関数は、アプリで最初に実行される関数です。 SFCApplet::Boot 関数では、ライセンスコードを設定し、 ClassID が "AEECLSID_HELLOWORLD" ( HelloWorld アプリケーションクラス ) の Factory 関数を返します。

SFCApplet::Boot 関数の次に実行されるのが Factory 関数です。 Factory 関数は、HelloWorld アプリケーションクラスのインスタンスを生成するコンストラクタを呼び出します。

[Note] ClassID とライセンスコード

実機の場合、ClassID に対応した正規のライセンスコードを設定しなければ、SFR アプリは起動しません。

開発用実機に製品パッケージの Example ディレクトリ内のサンプル アプリの ClassID とライセンスコードが利用可能です。

シミュレータでは、ライセンスコードを設定しなくても SFR アプリは起動します。

例 5.1. ブートローダとファクトリ関数

//
//  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;
}

5.2.2. アプリケーションクラスの定義

SFR GUI フレームワークを使う SFR アプリの HelloWorld クラスは SFRApplication クラスを継承します。

SFMTYPEDEFCLASS は HelloWorld に関する便利なユーザー定義型を自動生成するマクロです。

SFMSEALCOPY はインスタンスのコピーを禁止するマクロです。 SFRApplication クラスを継承するクラスのインスタンスはコピーしてはいけません。

HANDLER_DECLARE_VOIDRENDER(OnRenderContent) で描画ハンドラ、 HANDLER_DECLARE_BOOLEVENT(OnKey) でキーハンドラを宣言しています。

例 5.2. HelloWorld アプリケーションクラスの定義

//
//  HelloWorld.hpp
//

#ifndef __HELLOWORLD_HPP
#define __HELLOWORLD_HPP

#include <SophiaFramework.hpp>
#include "HelloWorld.bid"

//
//  HelloWorld アプリケーションクラス
//
SFMTYPEDEFCLASS(HelloWorld)
class HelloWorld : public SFRApplication {
    SFMSEALCOPY(HelloWorld)
public:
    static SFCInvokerPtr Factory(Void);
private:
    HelloWorld(Void) static_throws;
    virtual ~HelloWorld(Void);
    HANDLER_DECLARE_VOIDRENDER(OnRenderContent)
    HANDLER_DECLARE_BOOLEVENT(OnKey)
};

#endif // __HELLOWORLD_HPP //
[Note] SFC アプリの場合

GUI フレームワークを使わない SFC アプリSFCApplication クラスを継承します。

5.2.3. コンストラクタの実装

アプリケーションクラスのコンストラクタでは、 RegisterHandler 関数を使用してイベントハンドラ関数を登録するなどして、アプリケーションクラスのインスタンスを生成します。 RegisterHandler 関数の引数として、イベントコード、イベントコードに付随するデータ、イベントハンドラ関数を呼び出すタイミング、イベントハンドラ関数へのポインタを渡します。

例 5.3. コンストラクタの実装

// コンストラクタ
HelloWorld::HelloWorld(Void) static_throws
{
    if (static_try()) {
        static_throw(
            RegisterHandler(SREVT_RESPONDER_RENDER, 
                            SRP16_RENDER_CONTENT,
                            HANDLER_BEFORE, 
                            HANDLER_FUNCTION(OnRenderContent)));
    }
    if (static_try()) {
        static_throw(
            RegisterHandler(SFEVT_KEY, 
                            HANDLER_AFTER, 
                            HANDLER_FUNCTION(OnKey)));
    }
    return;
}

5.2.4. デストラクタの実装

アプリの終了時にはデストラクタが呼び出され、デストラクタはアプリケーションクラスのインスタンスを破棄します。 ウィンドウやコントロールなどの全ての UI コンポーネントは自動的に破棄されます ( UI コンポーネントに関する破棄処理のコードは不要です )。

例 5.4. デストラクタの実装

// デストラクタ
HelloWorld::~HelloWorld(Void)
{
    return;
}

5.2.5. イベントハンドラの実装

イベントハンドラはイベントが発生した時の処理を記述するための関数です。

描画イベントが発生した時の処理は描画ハンドラ HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics) で定義します。

キー押下イベントが発生した時の処理はキーハンドラ HANDLER_IMPLEMENT_BOOLEVENT(HelloWorld, OnKey, event) で定義します。

5.2.5.1. 描画ハンドラの実装

graphics->DrawText 関数を使用して、文字列 "Hello World" を画面に表示します。

[Caution] 注意
GUI フレームワークを使う SFR アプリでは、すべての描画処理は描画ハンドラ内で行わなければいけません。 ( 描画ハンドラの外で行われた描画に対しては開発者がすべての状態を管理する必要があります )

例 5.5. 描画ハンドラの実装

// 描画ハンドラ
HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics)
{
    graphics->DrawText("Hello World", GetContentWorld());
    return;
}

5.2.5.2. キーハンドラの実装

セレクトキーのキーイベントを受信したとき、アプリを終了するキーハンドラの定義です。

例 5.6. キーハンドラの実装

// キーハンドラ
HANDLER_IMPLEMENT_BOOLEVENT(HelloWorld, OnKey, event)
{
    switch (event.GetP16()) {
        case AVK_SELECT: // セレクトキーのキーイベントを受信したとき
            Terminate(); // アプリを終了する
            return true;
    }
    return false;
}
[Caution] 注意

Terminate 関数を呼び出すと、デストラクタが呼び出されてアプリは終了します。

5.2.6. グローバル変数の定義とアクセス

アプリケーションクラスのインスタンスは、アプリ内のどこからでも SFRApplication::GetInstance 関数を使用してアクセスできます。 このため、グローバルな変数は下記のようにアプリケーションクラスに定義します。

例 5.7. グローバルな変数の定義とアクセス

//
//  ExampleAppli アプリケーションクラス(AppWizard で自動生成)
//
SFMTYPEDEFCLASS(ExampleAppli)
class ExampleAppli : public SFRApplication
{
    SFMSEALCOPY(ExampleAppli)
public:
    static SFCInvokerPtr Factory(Void);
private:
    explicit ExampleAppli(Void) static_throws;
    virtual ~ExampleAppli(Void);

    // グローバル変数 global_something_val を定義する
    SInt32 global_something_val;
public:
    // グローバル変数 global_something_val にアクセスするための GetGlobalSomethingVal 関数を宣言する
    SInt32 GetGlobalSomethingVal();
};

// グローバル変数 global_something_val にアクセスするための GetGlobalSomethingVal 関数を定義する
ExampleAppli::GetGlobalSomethingVal(Void)
{
    return global_something_val;
}

// GetGlobalSomethingVal 関数経由でグローバル変数 global_something_val の値を取得する
static_cast<ExampleAppliPtr>(SFRApplication::GetInstance())->GetGlobalSomethingVal();

5.2.7. エラー処理の機構

コンストラクタで使用している static_try 関数と static_throw 関数は、 エラー値を検証するための関数とエラー値を設定するための関数です。

設定されたエラー値は static_catch 関数で取得できます。 通常、static_catch 関数はエラー値を throw するクラスを利用する側で使います。

例 5.8. エラー値をキャッチしエラー処理するコード

helloworld = ::new HelloWorld();
switch( helloworld->static_catch() ){

        // エラー値に応じてエラー処理をする

};

static_exception クラスはエラー値を管理する変数を持っています。 この変数はテンプレート型で通常 SFCError 型が利用されます。

static_exception クラスの存在意義は、コンストラクタやオペレータでのエラー値を外部に搬出する、一般的な規約を制定する点にあります。