Palm Programmer's Laboratory
Palm OS Programmer's Companion Volume I/11-1
11-1 フィーチャ
フィーチャとは 32 ビットの値で、フィーチャの登録元にもそのユーザーにも特別な意味を持っています。フィーチャはシステムにもアプリケーションにも登録できます。Palm OSのシステムフィーチャの完全な一覧は Palm OS Programmer's API Reference の“フィーチャ定数”を参照して下さい。
各フィーチャはフィーチャクリエータとフィーチャ番号で識別されます。
- フィーチャクリエータは PalmSource 社に登録された一意なクリエータIDです。通常はフィーチャを作成するアプリケーションのクリエータlDを使用します。
- フィーチャ番号は特定のクリエータのフィーチャを互いに区別するための任意の 16 ビット値です。
一度フィーチャが登録されると、そのフィーチャは明示的に登録解除されるかハンドヘルドがリセットされるまで有効になります。アプリケーションによって登録されたフィーチャは、そのアプリケーションが終了しても有効なままです。
このセクションでは、フィーチャマネージャについて以下のトピックで説明します。
- システムバージョンフィーチャ
- アプリケーション定義のフィーチャ
- フィーチャマネージャの使用
- フィーチャメモリ
システムバージョンフィーチャ
フィーチャの例として、システムバージョンがあります。このフィーチャはシステムによって公開されているもので、システムのバージョンを表現する 32ビット値を含んでいます。システムバージョンはフィーチャクリエータが sysFtrCreator、フィーチャ番号は sysFtrNumROMVersion になっています。現在、システムソフトウェアのそれぞれのバージョンは以下の値を持っています。
0x01003001 | Palm OS 1.0 |
0x02003000 | Palm OS 2.0 |
0x03003000 | Palm OS 3.0 |
0x03103000 | Palm OS 3.1 |
0x03203000 | Palm OS 3.2 |
0x03503000 | Palm OS 3.5 |
0x04003000 | Palm OS 4.0 |
しかし、上に示したような意味不明瞭な定数をコード中に固定してしまうよりも、sysMakeROMVersion マクロ(SystemMgr.h で定義されています)を使用してバージョン番号を作成し、それを比較などに使用した方が良いでしょう。このマクロは5つのパラメータをとります。
- メジャーバージョン番号
- マイナーバージョン番号
- フィックスレベル
- ビルドステージ(以下のいずれか)
- sysROMStageDevelopment
- sysROMStageAlpha
- sysROMStageBeta
- sysROMStageRelease
- ビルド番号
フィックスレベルとビルド番号には通常ゼロを指定し、ビルドステージには通常 sysROMStageRelease を指定します。sysFtrNumROMVersion が sysMakeROMVersion マクロで作成したバージョン番号以上であるかどうかを確認するには、以下に示すように単純なチェックを行ないます。
// See if we're on ROM version 3.1 or later. FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); if (romVersion >= sysMakeROMVersion(3, 1, 0, sysROMStageRelease, 0)) { .... }
その他のシステムフィーチャは SystemMgr.h に定義されています。システムフィーチャは ROM 内のフィーチャテーブルに保存されています(Palm OS 3.1 以降では、このテーブルの内容はシステムの起動時点で RAM 上のフィーチャテーブルにコピーされます)。システムフィーチャをチェックし、特定の機能の有無に合わせて振舞いを変えることで、アプリケーションは複数のバージョンのシステムとの互換性を保つことができます。将来のハードウェアプラットフォームでは現在のプラットフォームに存在する機能がなくなる可能性もあるため、システムバージョンフィーチャをチェックすることは重要です。
- IMPORTANT
- ベストな結果を得るために、特定のAPIが利用可能かどうかを調べる場合にシステムバージョン番号だけに頼るのではなく、対応するフィーチャをチェックすることをお勧めします。フィーチャのチェックに関する詳細は、Palm OS Programmer's API Reference の付録“互換性ガイド”を参照して下さい。
アプリケーション定義のフィーチャ
フィーチャマネージャは、アプリケーションに閉じた使い方でも有用な場合があります。例えば、アプリケーションは起動コードを処理するのに必要なプライベートなデータを指すポインタを含むフィーチャを公開したい場合があります。通常、アプリケーションのグローバル領域は起動コードの処理時には使用できないため、フィーチャマネージャの使用はアプリケーションにとってそのようなデータを取得するもっとも簡単な方式になります。
フィーチャマネージャは ROM 上のフィーチャテーブルと同様、RAM 上でも1つのフィーチャテーブルを管理します。アプリケーション定義のフィーチャは RAM 上のフィーチャテーブルに保存されます。
フィーチャマネージャの使用
特定すればフィーチャが存在するかどうかをチェックするには、FtrGet をコールしてフィーチャクリエータとフィーチャ番号を渡します。フィーチャが存在していれば、FtrGet はフィーチャの値を 32ビット値で返します。フィーチャが存在しなければ、エラーコードが返されます。
新たなフィーチャを登録したり既存のフィーチャの値を変更するには、FtrSet をコールしてフィーチャクリエータとフィーチャ番号、およびフィーチャの値を 32ビット値で渡します。登録されたフィーチャは、 FtrUnregister のコールで明示的に登録解除されるか、システムがリセットされるまでは有効なまま残ります。単純にアプリケーションを終了しただけでは、アプリケーションが登録したフィーチャは削除されません。
FtrSet をコールして作成したフィーチャは、FtrUnregister をコールすることで削除します。
登録されているフィーチャの完全な一覧は、FtrGetByIndex を繰り返しコールすることで得られます。FtrGetByIndex に 0 から始まるインデックスを渡し、1 ずつインクリメントしていくことで、全ての利用可能なフィーチャを得ることができます。FtrGetByIndex には、ROM と RAM のどちらのフィーチャテーブルを検索するかをパラメータで指定できます。Palm OS 3.1 以降では、ROM テーブルはシステムのスタートアップ時に RAM テーブル内にコピーされます。そのため、RAM テーブルはシステム全体のフィーチャを保有します。
フィーチャメモリ
Palm OS 3.1 より、フィーチャメモリのサポートが追加されました。フィーチャメモリはアプリケーション呼び出しを跨ぐ永続的なデータへの素早く効率的なアクセスを提供します。フィーチャメモリに保存されたデータは、ハンドヘルドがリセットされるか明示的に開放するまで存続します。フィーチャメモリはストレージヒープ上に割り当てられたメモリです。従って、フィーチャメモリへの書込みには DmWrite を使用します。このことは、フィーチャメモリへの書込みがデータベースへの書込みよりも速いわけではないことを意味します。しかし、フィーチャメモリは特定の状況においてより効率的なアクセスを提供できます。
フィーチャメモリにチャンクをアロケートするには、FtrPtrNew をコールします。パラメータとして、フィーチャクリエータとフィーチャ番号、アロケートするバイトサイズ、およびアロケートしたチャンクのアドレスの格納先を指定します。以下に例を示します。
FtrPtrNew(appCreator, myFtrMemFtr, 32, &ftrMem);
アプリケーションの別の場所では、FtrGet を使用してフィーチャメモリのチャンクを指すポインタを取得できます。
- NOTE
- Palm OS 3.5 より、FtrPtrNew は 64KB を越えるチャンクのアロケートが可能になりました。大きなメモリチャンクをアロケートする際の一般的な問題は意識しておく必要があります。十分な連続領域が存在しない場合があること、およびシステムのパフォーマンスに影響する可能性があることです。
フィーチャメモリはパフォーマンスの最適化と考えることができます。フィーチャメモリを使用するような一般的状況というものはなく、典型的なアプリケーションでは使うことはないでしょう。フィーチャメモリは以下のようなコードで使用されます。
- 稀にしか実行されない
- 大域にアクセスできない
- 稀にしか変更されず、32 ビットのフィーチャ値に保存できないようなデータにアクセスする必要がある
例えば、起動コードへの応答で呼ばれる関数を書いているとしましょう。そしてその起動コードは頻繁に受信することが想定されます。この関数がアプリケーションのプリファレンスデータベースにアクセスする必要があるとします。関数の開始時点で、データベースをオープンしてデータを読み込む必要があります。関数が頻繁にコールされると、毎回データベースをオープンすることがパフォーマンスの低下を招きます。別の方法として、フィーチャメモリからチャンクをアロケートして必要なデータを書き込んでおくことができます。このチャンクはハンドヘルドがリセットされるまで存続するため、データベースをオープンする必要があるのは1回だけです。リスト 11.1 にこの例を示します。
リスト 11.1 フィーチャメモリの使用
MyAppPreferencesType prefs; if (FtrGet(appCreator, myPrefFtr, (UInt32*)&prefs) != 0) { // Feature memory doesn't exist, so allocate it. FtrPtrNew(appCreator, myPrefFtr, 32, &thePref); // Load the preferences database. PrefGetAppPreferences (appCreator, prefID, &prefs, sizeof(prefs), true); // Write it to feature memory. DmWrite(thePref, 0, &prefs, sizeof(prefs)); } // Now prefs is guaranteed to be defined.
フィーチャメモリのもう1つの有効な使い方は、通常の 32 ビットのフィーチャ値には収まらないようなデータをアプリケーションやライブラリから他のアプリケーションに“公開”する場合です。例えば、通信ライブラリを書いていて、クライアントアプリケーションが接続状態を描画するために使用するアイコンを公開したいとします。ライブラリで FtrPtrNew によりフィーチャメモリチャンクをアロケートし、現在の状態を表すアイコンを保存することができます。アプリケーションは FtrGet によってアイコンにアクセスし、その結果を WinDrawBitmap に渡すことで現在の接続状態をスクリーンに描画することができます。