前のページ次のページ上に戻るホーム BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework 4.1

3.1. SophiaFramework アプリ

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

3.1.1. アプリの起動

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

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

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

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

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

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

例 3.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;
}

3.1.2. アプリクラスの定義

GUI フレームワークを使うので、HelloWorld クラスは SFRApplication クラスを継承します。

[Note] 注意
GUI フレームワークを使うアプリは SFR アプリと呼びます

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

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

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

例 3.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 クラスを継承します。

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

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

例 3.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;
}

3.1.4. デストラクタの実装

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

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

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

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

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

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

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

3.1.5.1. 描画ハンドラの実装

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

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

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

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

3.1.5.2. キー ハンドラの実装

セレクト キーが押されたとき、アプリを終了するキー ハンドラの定義です。

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

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

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

3.1.6. エラー処理の機構

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

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

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

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

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

};

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

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