Prototype > C++ アプリケーションでプロトタイプを使用する > プロトタイプの高度な使用 > 新規アクセサー・クラスの記述
 
新規アクセサー・クラスの記述
Prototypes パッケージには、プロトタイプで複雑な振る舞いの定義を可能にする多くの定義済みアクセサー・クラスが含まれています。しかし、特殊なニーズのために特殊な振る舞いを実装する場合もあります。このセクションでは、プロトタイプ構築のためにアクセサー・クラスのセットを拡張する方法を説明します。独自の新しいアクセサー・クラスがどのように Rogue Wave® Views Studio に統合されるかについても説明します。
アクセサーのクラスを追加するには、2 つのクラスを記述する必要があります。
*新規アクセサーの効果を定義する IlvUserAccessor のサブクラス。
*アクセサーが Rogue Wave Views Studio で編集される方法を定義する IlvAccessorDescriptor のサブクラス。
Rogue Wave Views 配布ディレクトリーの <ILVHOME>/samples には、新規アクセサー・クラスの例があります (gpacc.h および gpacc.cpp ファイル)。詳細については、ディレクトリーの README ファイルを参照してください。
IlvUserAccessor のサブクラス化
新規アクセサー・クラスを定義するには、IlvUserAccessor の直接サブクラスを記述するか、拡張したい機能を実装している既存のサブクラスから派生させます。このクラスを永続化させることもできます。
サブクラスの定義
IlvUserAccessor のサブクラスの宣言は、通常、次のようになります。
class MyAccessor:public IlvUserAccessor {
public:
MyAccessor(const char* name,
const IlvValueTypeClass* type,
const char* param1,
const char* param2);
DeclareUserAccessorInfo();
DeclareUserAccessorIOConstructors(MyAccessor);
protected:
IlvSymbol* _param1;
IlvSymbol* _param1;
virtual IlBoolean changeValue(IlvAccessorHolder* object,
const IlvValue& val);
virtual IlvValue& queryValue(const IlvAccessorHolder* object,
IlvValue& val) const;
}
次のメソッドは、新規アクセサー・クラスを作成するために再定義します。
*MyAccessor
MyAccessor(const char* name,
const IlvValueTypeClass* type,
const char* param1,
const char* param2);
このコンストラクターは、コードでアクセサーのインスタンスを作成するために使用されます。Rogue Wave Views Studio では、入力コンストラクターのみが使用されます。name パラメーターは、アクセサーによって処理されるアトリビュートの名前を定義し、type パラメーターは、アトリビュートのタイプを定義します。コンストラクターには、 param1 などの追加パラメーターがあります。これらのパラメーターは、Rogue Wave Views Studio で入力することができ、実行時に評価されるパラメーターに対応する文字列になることがよくあります。
*changeValue
virtual IlBoolean changeValue(IlvAccessorHolder* object,
const IlvValue& val);
アクセサーによって扱われるアトリビュートがプロトタイプ上、またはそのインスタンスの 1 つで、changeValue への呼び出しを使って変更されたときに changeValue メソッドが呼び出されます。このメソッドを使用して、アクセサーの値変更の効果を定義します。アクセサーがパラメーターを使用する場合、これらのパラメーターを評価しなくてはなりません。これは、直接値あるいは他のアクセサーの名前のいずれかを含む文字列を評価する getValue メソッドを使用して行うことができます。
object パラメーターは、アクセサーが付加されるプロパティーあるいはプロパティー・インスタンスです。val パラメーターは新しい値を含んでいます。changeValue メソッドは、値の変更に成功した場合 IlTrue を返し、エラーが生じたときは IlFalse を返します (たとえば、パラメーターの 1 つが評価できなかった場合)。
*queryValue
virtual IlvValue& queryValue(const IlvAccessorHolder* object,
IlvValue& val) const;
アクセサーによって扱われるアトリビュートがプロトタイプ上、またはそのインスタンスの 1 つで、queryValue への呼び出しを使って取得されたときに queryValue メソッドが呼び出されます。このメソッドは、アクセサーの「現在の」値をその val パラメーター内に保存する必要があります (それが適切な場合)。アクセサーの中には現在の値を保存するものもあれば、保存しないもの (たとえば、条件アクセサーはその値を保存しません) もあります。現在の値は、IlvValue の代入演算子を使用して val パラメーターに保存されます。メソッドはその val パラメーターを返さなくてはなりません。
*initialize
virtual void initialize(const IlvAccessorHolder* object);
initialize メソッドは、アクセサー・オブジェクトがプロトタイプあるいはプロトタイプ・インスタンスに関連付けられるときに呼び出されます。このメソッドを再定義して、あらゆる種類の初期化を実行することができます。
IlvUserAccessor サブクラスの永続化
グラフィック・オブジェクトのように、アクセサー・オブジェクトは永続的である必要があります。つまり、プロトタイプ定義ファイルに保存され、プロトタイプがロードされるときに読み込まれなくてはなりません。アクセサー・オブジェクトの永続化機構は、グラフィック・オブジェクトに使用する機構ととてもよく似ています。
まず、アクセサー・クラスの .h ファイルで、クラス宣言の public セクションの次のマクロを呼び出します。
DeclareUserAccessorInfo();
DeclareUserAccessorIOConstructors(MyAccessor);
これは自動的に Rogue Wave Views 実行時タイプ情報をサブクラス用に作成し、永続性を宣言してメソッドをコピーします。
.cpp ファイルで、次のメソッドを記述する必要があります。
*MyAccessor(IlvDisplay* display, IlvGroupInputFile& f)
*MyAccessor::MyAccessor(const MyAccessor& source)
*MyAccessor::write(IlvGroupOututFile& f) const
このコンストラクターは、アクセサー・オブジェクトの記述を入力ストリームから読み込みます。IlvGroupInputFile クラスは、IlvInputFile に類似しています。一般的には、その getStream メソッドのみを使用します。これは、istream オブジェクトへのリファレンスを返し、そこからアクセサー・オブジェクトの記述を読み込むことができます。ただし、便利なメソッド readValue を使用することもできます。writeValue メソッドは、スペースを含む文字列の周りに引用符を付け、readValue メソッドは、これらの引用符をチェックして文字列を正しく読み込みます。これらのメソッドを組み合わせて使用することで、入力/出力エラーを回避します。たとえば、メソッドの実装は、下記のようになります。
MyAccessor::MyAccessor(IlvDisplay* display, IlvGroupInputFile& f)
: IlvUserAccessor(display, f)
{
_param1 = f.readValue();
_param2 = f.readValue();
}
次に、プロトタイプがコピーされたとき、あるいはプロトタイプのインスタンスが作成されたときに呼び出されるコピー・コンストラクターを記述します。
MyAccessor::MyAccessor(const MyAccessor& source)
: IlvUserAccessor(source)
{
_param1 = source._param1;
_param2 = source._param2;
}
write メソッドは、アクセサーの記述を保存するために再定義します。パラメーターの保存に使用するフォーマットは、入力コンストラクターによって定義されているフォーマットと一致させます。
MyAccessor::write(IlvGroupOututFile& f) const
{
IlvUserAccessor::write(f);
f.writeValue(_param1); f << IlvSpc();
f.writeValue(_param2); f << endl;
}
最後に、次のマクロを.cpp ファイルで呼び出します。
IlvPredefinedUserAccessorIOMembers(MyAccessor)
IlvRegisterUserAccessorClass(MyAccessor,IlvUserAccessor);
IlvAccessorDescriptor のサブクラス化
IlvUserAccessor のサブクラスを記述後、別のクラス、IlvAccessorDescriptor のサブクラスを記述します。このクラスは、Rogue Wave Views Studio のグループの詳細情報がアクセサー・クラスのパラメーターを編集するために必要な情報を提供します。
IlvAccessorDescriptor サブクラスの名前は、IlvUserAccessor のサブクラスの名前と一致させます。たとえば、アクセサー・クラスが MyAccessor である場合、記述子クラスは MyAccessorDescriptorClass と呼ぶ必要があります。
ここでは、アクセサー記述子クラスだけを宣言すればいいようになっています。インスタンスは自動的に作成され、IlvRegisterUserAccessorClass マクロによってユーザー・アクセサー・サブクラスに関連付けられます。
次は、記述子クラスの一般的な例です。
class MyAccessorDescriptorClass :
public IlvAccessorDescriptor {
public:
MyAccessorDescriptorClass()
: IlvAccessorDescriptor("MyAccessor:an example",
Miscellaneous,
"example %s %s...",
IlFalse,
&IlvValueIntType,
0,
2,
"Parameter #1", &IlvValueParameterTypeString,
"Parameter #2", &IlvNodeNameParameterType) {}
};
アクセサー記述子クラスは、引数のないコンストラクターを要求するだけです。IlvAccessorDescriptor コンストラクターを呼び出さなくてはなりません。このコンストラクターのパラメーターの詳細は、IlvAccessorDescriptor クラスの説明を参照してください。

Version 6.0
Copyright © 2015, Rogue Wave Software, Inc. All Rights Reserved.