イベントマネージャとコンソールサービスの作成


ソフトウェアコンポーネント作り方のより具体的な例として、イベントマネージャとコンソールの作成手順を紹介します。

イベントマネージャおよびコンソールサービスは、サービスを提供するインターフェイスポインタをシステムの名前空間に登録に登録することによって、名前空間からそのインターフェィスポインタを取得したそのほかのプロセスからキーボードやマウスからの入力を処理したり、SVGA画面上に文字を表示したりできるようにします。

イベントマネージャ

イベントマネージャは、キーボード、マウスからの入力を管理するコンポーネントです。eventManager.cppをビルドしてできる実行可能ファイル(eventManager.elf)がイベントマネージャです。

イベントマネージャがなかったバージョン0.0.11以前のesオペレーティングシステムでは、キーボード、マウスのローレベルの入力をアプリケーションごとに管理する必要がありました。 例えばSqeuakは、別スレッドでキーボード、マウスのローレベルの入力を直接監視していました。 しかし、すべてのアプリケーションが個別に入力を監視していたのでは、複数のプロセスが入力を奪い合うことになってよくありません。 そこで、キーボード、マウス入力の管理をイベントマネージャ コンポーネントにまとめ、それを他のアプリケーションから利用することにします。

イベントマネージャはもともとSqueak用に実装していたキーボード、マウス入力を監視する機能を再利用して作成しました。 以前のバージョンのSqeuakでは、EventQueueというクラスでキーボード、マウス入力を管理していました。 この機能をコンポーネント化するために、新たにIEventQueueインターフェイスを定義し、EventQueueを切り出して 作成する EventManager クラス では、この IEventQueueインターフェイスを実装するようにします。そしてイベントマネージャの提供する IEventQueueインターフェイスを名前空間 に登録することによってその他のプロセスがイベントマネージャを利用できるようになります。名前空間の使い方については次の節で説明します。

イベントマネージャは、インターフェイスを登録した後、EventManagerクラスを利用してキーボード、マウス入力の監視を始めます。

名前空間への登録

ここでは、コンポーネントのインターフェイスポインタを名前空間に登録する方法を説明します。

esオペレーティングシステムでは名前空間に、名前とインターフェイスポインタの組を登録できるようになっています。(詳しくは、esオペレーティングシステムの名前空間を参照してください。)

名前空間への登録は簡単です。まずSystem()->getRoot()を呼び出して、名前空間のルートへのIContextインターフェイスポインタを取得します。bindメソッドを使うと、 インターフェイスに名前を付けて名前空間に登録することができます。

下記の例では、IStreamインターフェイスポインタをconsoleという名前で、名前空間の"/device/console"に登録します。


Handle<IStream> stream = ... // ISreamインターフェイスポインタを用意します。

Handle<IContext> nameSpace = System()->getRoot(); // 名前空間のルートを取得します。
Handle<IContext> device = nameSpace->lookup("device"); // 既存の名前空間 "/device" を検索します。
device->bind("console", stream); // "/device"の下に、"console"という名前でstreamを登録します。

独自インターフェイスの登録

上記の例で利用したIStreamインターフェイスは、カーネルに初期登録されているインターフェイスです。 一方、IEventQueueインターフェイスはイベントマネージャが独自に定義したインターフェイスです。 そのため、名前空間に登録する前に、カーネルに登録しなければなりません。

登録手順は下記のようになります。(詳しくは、ソフトウェアコンポーネントの作り方の「インターフェイスの拡張」を参照してください。 )


Handle<IContext> nameSpace = System()->getRoot();

// Register IEventQueue interface.
Handle<IInterfaceStore> interfaceStore = nameSpace->lookup("interface");
interfaceStore->add(IEventQueueInfo, IEventQueueInfoSize);

以上で準備は完了です。 下記のようにして、IEventQueueインターフェイスを名前空間 "/device/event"に登録します。


// Create Event manager object.
Handle<IEventQueue> eventQueue = new EventManager;

// register the event queue.
Handle<IContext> device = nameSpace->lookup("device");
device->bind("event", static_cast<IEventQueue*>(eventQueue));

イベントマネージャ コンポーネントは、始めに下記の2種類の登録を行います。

コンポーネントの利用

イベントマネージャを利用する前に、 イベントマネージャ コンポーネント(eventManager.elf)を新しいプロセスとして実行します。


Handle<IProcess> eventProcess;
eventProcess = reinterpret_cast<IProcess*>(
    esCreateInstance(CLSID_Process, IProcess::iid())); // プロセス作成

Handle<IFile> eventElf = nameSpace->lookup("file/eventManager.elf"); // コンポーネント読み込み
eventProcess->setRoot(nameSpace); // 新プロセスの名前空間のルートを設定

eventProcess->setIn(esReportStream()); // 標準入力の設定
eventProcess->setOut(esReportStream()); // 標準出力の設定
eventProcess->setError(esReportStream()); // 標準エラー出力の設定

eventProcess->start(file); // イベントマネージャ開始

これ以後は、名前空間から IEventQueueを取得して、利用できるようになります。


Handle<IContext> nameSpace = System()->getRoot();
Handle<IEventQueue> eventQueue = nameSpace->lookup("device/event"); // IEventQueueの取得

int x;
int y;
eventQueue->getMousePoint(x, y); // マウス座標の取得

int stroke;
eventQueue->getKeystroke(&stroke); // キー入力の取得

コンソールサービス

ソフトウェアコンポーネントの2つ目の例として、コンソールサービスを説明します。 コンソールは、次の機能を持ちます。

なお、コンソールサービスはSVGA画面へのフォントのレンダリングにFreeTypeを利用しています。

console.elf をプロセスとして実行すると、 コンソール機能を提供するIStreamインターフェイスポインタが 名前空間の"/device/console" に登録されます。コンソールのインターフェイスポインタは 次のようにして取得できます。


Handle<IStream> console = nameSpace->lookup("device/console"); // コンソールの取得

またコンソールはIStreamインターフェイスを提供するので、新しいプロセスの標準入出力先をコンソールに設定することもできます。


Handle<IProcess> process;
process = reinterpret_cast<IProcess*>(
    esCreateInstance(CLSID_Process, IProcess::iid()));
Handle<IFile>file = nameSpace->lookup("file/esjs.elf"); // 任意のコンポーネントを読み込み
process->setRoot(nameSpace);

process->setIn(console); // 標準入力をコンソールに設定
process->setOut(console); // 標準出力をコンソールに設定
process->setError(console); // 標準エラー出力をコンソールに設定

process->start(file);

esオペレーティングシステムのコマンドラインシェルを実行しているECMAScriptインタープリタesjsは、es.cppのなかで上記のように コンソールを標準入出力として設定して起動されています。

[esオペレーティングシステムのホームページに戻る]


Copyright © 2007
Nintendo Co,. Ltd.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Nintendo makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

SourceForge.jp