コマンドを追加する方法

新しいクラスを実装して、それをKONOEコマンド言語から制御をしたい場合の、 コマンド組み込みの方法について説明します。

1.概要

KONOEコマンド言語処理系では一つのクラスオブジェクトに一つのOrderly (当番兵)を割り当てます。新規にクラスを実装した場合、それに対応した Orderlyクラスをつくる必要があります。

OrderlyクラスはOfficerクラスに登録をします。さらにOfficerはCommanderに 登録されます。Commander→Officer→Orderlyという指揮系統を通して命令が 伝達されます。

Orderlyクラスに命令を登録することで機能を利用することができるように なります。addCommandメソッドでコマンドを追加します。addCommandメソッドは 引数にKonoeCommandProcessorを 継承した命令オブジェクトをとります。命令オブジェクトを定義するためには KonoeCommandDescriptorで 命令語や引数の数・型などを指定する必要があります。

2.Orderlyクラスの準備

2.1.クラス定義ファイルの用意

対象とするクラスを、たとえばKonoeSoftwareCrateとすると、それに対応した KonoeSoftwareCrateOrderlyというクラスを用意します。このクラスは KonoeOrderlyクラスを継承します。 いくつかの仮想メンバー関数を上書きする必要があります。それは およそ次のようなメンバーになります。
#include	<ui/KonoeOrderly.hh>

class KonoeSoftwareCrateOrderly : public KonoeOrderly {

public :
	KInt	createObject( KonoeCommand * cmd );
	KInt	deleteObject( KonoeCommand * cmd );
	KInt	showTarget( KonoeCommand * cmd );
	KInt	isOrderlyOf( void * target );
	KonoeOrderly	* clone( KChar * name );
	void	* getTarget( );
	void	setTarget( void * target );
};

2.2.識別番号と名前

Orderlyは固有の識別番号と名前を持ちます。識別番号はカテゴリー マネージャが知っている番号を使うとよいでしょう。
//クラス定義の中
public :
	enum	{	CLASS_ID = KonoeCategories::DATASOURCE +
			KonoeDataSourceCM::CID_SOFTWARECRATE	};
...
//コンストラクタの中
	setClassID( CLASS_ID );
などと記述します。

また、Orderlyはクラスの名前とオブジェクトの名前を持つことになります。 まずクラスの名前を定義しなければなりません。

//クラス定義の中
protected :
	static const KChar	* classname;
public :
	const KChar	* getClassName( ) { return classname; }
...
//.ccファイル中

const KChar	* KonoeSoftwareCrateOrderly::classname = "SoftwareCrate";

これにより、コマンド処理系の中でこのOrderlyはSoftwareCrateという 名前で参照できるようになります。

2.3.コマンドの定義

KonoeOrderlyを継承しただけでは、まだ命令は登録されていません。 まず、コマンドを定義します。一つ一つのコマンドは KonoeCommandProcessorを継承して 実装されます。このクラスのexecuteメソッドを上書きすることで、それぞれの 仕事をさせます。

このクラスはOrderlyの中でだけ使われます。それ故、クラス内クラスとして スコープを限定して定義をします。create(クラスオブジェクトを生成する) やhelpなどの共通的な命令は、それぞれ KonoeCreateCommandKonoeHelpCommand として実装されています。ここではaddコマンドを定義しましょう。

#include	<ui/KonoeCommandProcessor.hh>
...
//クラス定義の中

	class AddUnit : public KonoeCommandProcessor {
	public :
		AddUnit( KonoeCommandDescriptor * cd, KonoeOrderly * owner );
		KInt	execute( KonoeCommand * cmd );
	};

それぞれのメンバー関数の中身はKonoeSoftwareCrateOrderlyのファイルをみてください。

2.4.コマンドの登録

とりあえず、コマンドプロセッサが用意されると、それを登録します。 Orderlyのコンストラクタの中で登録します。まず、コマンド記述子を用意し、 それからコマンドプロセッサを生成します。それをaddCommandメソッドで 登録します。

//クラス定義の中

	enum	{	ARG_ADD_MODULE,
			N_ARG_ADD	};

//addコマンドが引数を一つとることをenumで表します。

//コンストラクタの中

	KonoeCommandDescriptor	* cd;
	KonoeArgumentDescriptor	* ad;

	cd = new KonoeCommandDescriptor( "add", N_ARG_ADD );
	ad = new KonoeArgumentDescriptor( "module",
			STRING, NECESSARY );
	ad -> setDescription( "Name of module to be installed" );
	cd -> add( ad );
	cd -> setDescription( "Install a software module to the crate" );

	addCommand( new AddUnit( cd, this ) );

これで、add命令が使えるようになりました。

2.5.executeメソッドの書き方

KonoeCommandProcessorのexecuteメソッドを上書きして実際の仕事を させます。上述の例ではAddUnit::executeです。メソッドへの引数で KonoeCommandのオブジェクトが 渡されます。それが引数の情報や出力ストリームなどを与えます。

引数の数をチェックするには

	KInt	n_arg = cmd -> getArgumentCount( );
です。そして実際に引数を取り出すのは
	KonoeCommandArgument	* arg;

	arg = cmd -> getArgument( index );

ここではindex番目の引数が取り出されます。この引数オブジェクトから 実際に与えられた引数文字列を取り出す場合
	const KChar	* val = arg -> getValue( );
となります。

エラーメッセージなどの出力は、ネットワーク経由で操作される 場合などもあり、標準出力にする訳にはいきません。そのために、 KonoeCommandはその時点での出力ストリームを知っています。

	ostream & os = cmd -> getOutputStream( );

	os << "Error .. invalid argument : " << val << endl;
などとなります。

コマンド処理系ですでに定義されたオブジェクトを取り出したい場合が あります。それらの情報はOrderlyを統括するOfficerが知っています。 そのOrderlyと同じカテゴリーのオブジェクトを知りたいのであれば

	KonoeOfficer	* officer = owner -> getOfficer( );
	KonoeOrderly	* orderly = officer -> findObject( val );

3.Orderlyクラスの登録

OrderlyはOfficerに登録されている必要があります。それぞれの カテゴリーにOfficerがいます。今のケースではKonoeDataSourceOfficerが あります。そのコンストラクタで名前なしのOrderlyオブジェクトを 生成して登録します。
//KonoeDataSourceOfficer.ccのコンストラクタの中

	registerOrderly( new KonoeSoftwareCrateOrderly( 0 ) );

これで、KonoeDataSourceOfficerを雇ったコマンダーはこのOrderlyに アクセスできるようになりました。
[ File = konoe/ui/command/add_orderly.html ] last modified = 16-May-2001
KONOEコラボレーション konoe-req@konoe.kek.jp