ToolTalk ユーザーズガイド

第 10 章 静的メッセージパターン

定義済みのメッセージの集合を受信する場合、静的メッセージ方式は、メッセージパターン情報を指定する簡単な方法です。

静的メッセージの定義

静的メッセージ方式を使用するには、ユーザーのプロセス型とオブジェクト型を定義し、ToolTalk 型コンパイラの tt_type_comp によってコンパイルします。プロセス型を宣言すると、ToolTalk サービスはその型に基づいたメッセージパターンを作成します。静的メッセージパターンは、ToolTalk サービスとの通信を閉じるまで有効です。

プロセス型の定義

アプリケーションは、アプリケーションを実行しているプロセスがない場合でも、潜在的なメッセージの受信者であると考えられます。そのために、プロセス型 (ptype) ファイルにアプリケーションの起動方法に関するメッセージパターンと指示を提供します。これらの指示は、メッセージがアプリケーションを利用可能だがアプリケーションが起動していない場合、次の処置の 1 つを行うよう ToolTalk サービスに指示します。

ToolTalk サービスが情報を利用できるようにするため、アプリケーションのインストール時に、ToolTalk 型コンパイラの tt_type_comp によって ptype ファイルをコンパイルします。

アプリケーションが ToolTalk サービスに ptype を登録すると、ptype に表示されたメッセージパターンも自動的に登録されます。

ptype は、アプリケーションが起動していないときに ToolTalk サービスが使用する、アプリケーション情報を提供します。この情報は、必要に応じてプロセスを起動する場合のほか、メッセージを受信する場合またはプロセスが開始するまでメッセージを待ち行列に入れる場合に使用されます。

ptype は、プロセス型識別子 (ptid) で始まります。ptid の後には、次の項目が続きます。

  1. オプションの開始文字 — ToolTalk サービスは、必要に応じてこのコマンドを実行し、プログラムを実行するプロセスを起動します。

  2. シグニチャ — プログラムが受信対象とする、TT_PROCEDURE にアドレス指定したメッセージを記述します。監視対象のメッセージは、処理対象のメッセージとは別に記述します。

シグニチャ

「シグニチャ」は、プログラムが受信対象とするメッセージについて記述します。シグニチャは、矢印 (=>) によって 2 つの部分に分けられます。シグニチャの前半部分は、照合する属性値を指定します。シグニチャに指定する属性値の数が増えるほど、シグニチャが一致するメッセージの数は少なくなります。シグニチャの後半部分は、シグニチャの前半部分に一致したメッセージに ToolTalk サービスがコピーする受信側の値を指定します。

ptype のシグニチャは、処置および操作番号 (opnum) の値を持つことができます。ToolTalk サービスは、処置の値 (開始、待ち行列、またはデフォルトの破棄) を使用し、プログラムを実行しているプロセスがない場合に、シグニチャに一致したメッセージに対する処理を決定します。opnum 値は、メッセージの受信側にとって便利です。2 つのシグニチャの操作名が同じで引数が異なる場合は、異なる opnum によって着信メッセージを簡単に識別できます。

ptype ファイルの作成

次のコード例は、ptype ファイルを示しています。

#include "Sun_EditDemo_opnums.h"

ptype Sun_EditDemo {
		/* setenv Sun_EditDemo_HOME to install dir for the demo */
	 start	“${Sun_EditDemo_HOME}/edit”;
	 handle:
	 /* edit file named in message, start editor if necessary */
	 session Sun_EditDemo_edit(void)
					=> start opnum=Sun_EditDemo_EDIT;

	 /* tell editor viewing file in message to save file */
	 session Sun_EditDemo_save(void)
					=> opnum=Sun_EditDemo_SAVE;

	 /* save file named in message to new filename */
	 session Sun_EditDemo_save_as(in string new_filename)
					=> opnum=Sun_EditDemo_SAVE_AS;

	 /* bring down editor viewing file in message */
	 session Sun_EditDemo_close(void)
					=> opnum=Sun_EditDemo_CLOSE;
};

次に ptype ファイルの構文を示します。

ptype	::=	'ptype' ptid `{'
		property*		[`observe:' psignature*]
		[`handle:' psignature* ]
		[`handle_push:' psignature*]
		[`handle_rotate:' psignature*]
		`}' [`;']
property	::=	property_id value `;'
property_id	::=	`start'
value	::=	string
ptid	::=	identifier
psignature	::=	[scope] op args [contextdcl]
		[`=>'
		[`start'][`queue']
		[`opnum='number]]
		`;'
scope	::=	`file'
	|	`session'
	|	`file_in_session'
args	::=	`(` argspec {, argspec}* `)'
	|	`(void)'
	|	`()'
contextdcl	::=	`context' `(` identifier {, identifier}* `)' `;'
argspec	::=	mode type name
mode	::=	`in' | `out' | `inout'
type	::=	identifier
name	::=	identifier

property_id 情報

ptid — プロセス型識別子 (ptid) は、プロセスの型を識別します。ptid は、導入システムごとに一意でなければなりません。この識別子はインストール後は変更できません。したがって、選択する個々の名前は一意でなければなりません。たとえば、Sun_EditDemo のように、製品または会社の商標名を使用できます。ptid には、32 文字以内という制限があり、予約済み識別子 (ptype、otype、start、opnum、queue、file、session、observe、または handle) は使用できません。

start — プロセスの起動文字列。ToolTalk サービスが、プロセスを起動する必要がある場合は、シェルとして使われるコマンド /bin/sh を実行します。

コマンドを実行する前に、ToolTalk サービスは、アプリケーションを起動したメッセージのファイル属性値を使って、TT_FILE を環境変数として定義します。このコマンドは、アプリケーションを起動したメッセージ送信側の環境ではなく、ttsession の環境内で実行します。したがって、コンテキスト情報がある場合、メッセージ引数またはコンテキストによって渡される必要があります。

psignature 照合情報

scope — このパターン属性は、メッセージ内の配信範囲属性と照合されます。

op — 操作名。この名前は、メッセージ内の操作属性と照合されます。


注 –

ptype および otype の両方にメッセージシグニチャを指定する場合は、それぞれに固有の操作名を使用してください。たとえば、ptype と otype の両方に表示操作を指定することはできません。


args — 操作のための引数。args リストが void の場合、シグニチャは引数のないメッセージだけに一致します。args リストが空 (つまり ()) の場合は、シグニチャは引数とは無関係に一致します。

contextdcl — コンテキスト名。この名前の付いたコンテキストを持つパターンがシグニチャから生成される場合、パターンは空の値リストを持ちます。

psignature 処置情報

start — psignature がメッセージに一致しても、この ptype を持つ実行中のプロセスの中に、メッセージに一致したパターンを持つものがない場合は、この ptype のプロセスを起動します。

queue — psignature がメッセージに一致しても、この ptype を持つ実行中のプロセスの中にメッセージに一致したパターンを持つものがない場合は、この ptype のプロセスがメッセージに一致したパターンを登録するまでメッセージを待ち行列に入れます。

opnum — 指定された数をメッセージの opnum 属性に書き込み、メッセージと一致したシグニチャを識別できるようにします。

メッセージがシグニチャと一致するとき、シグニチャの opnum がメッセージに組み込まれます。これでアプリケーションは、tt_message_opnum 呼び出しによって opnum を検索できます。シグニチャごとに固有の opnum を指定すると、どのシグニチャがメッセージと一致したかすぐに判定できます。

tt_ptype_opnum_callback_add 呼び出しを使用すると、opnum にコールバックルーチンを接続できます。メッセージが一致すると、ToolTalk サービスはその opnum に接続されたコールバックをすべて調べ、それらを起動します。

Sun_EditDemo_opnums.h ファイルは、edit.c が使用するすべての opnum のシンボリック定義を定義します。これにより、edit.types ファイルと edit.c ファイルは、同じ定義を共有できます。

ツールの自動起動

ToolTalk サービスにツールを自動的に起動させる ptype 宣言の簡単な例を次に示します。これは、表示、編集、および構成対象のメッセージを受信し、そのメッセージを処理できるツールのインスタンスが 1 つも動作していない場合は、/home/toone/tools/mytest を起動し、そのメッセージを配信するというコード例です。


注意 – 注意 –

この例を実行すると、ToolTalk サービスはハンドラを無限に検索し続けます。


ptype My_Test {
    start "/home/toone/tools/mytest";
    handle:

	session Display (in Ascii text) => start;
	session Edit (inout Ascii text) => start;
	session Compose (out Ascii text) => start;

	file Display (in Ascii file_name) => start;
	file Edit (inout Ascii file_name) => start;
	file Compose (out Ascii file_name) => start;
};

オブジェクト型の定義

メッセージが、特定のオブジェクトまたはオブジェクト型にアドレス指定されている場合、ToolTalk サービスは、メッセージを配信するアプリケーションを判定できなければなりません。アプリケーションは、「オブジェクト型」(otype) にこの情報を提供します。otype はアプリケーションの ptype を指定します。ptype はオブジェクトを管理し、オブジェクトと関連するメッセージパターンを記述しています。

メッセージパターンには、メッセージは利用可能だがアプリケーションが起動していない場合の処理を ToolTalk サービスに示す指示が入っています。この場合、ToolTalk は次の指示のいずれか 1 つを実行します。

ToolTalk サービスがこのような情報を利用できるようにするために、アプリケーションのインストール時に ToolTalk 型コンパイラの tt_type_comp で otype ファイルをコンパイルします。オブジェクトを管理するアプリケーションは、ToolTalk サービスに登録する際に ptype を宣言します。ptype を登録するとき、ToolTalk サービスは ptype を示す otype の有無を調べ、otype 内で検索したパターンを登録します。

アプリケーションの otype は、ToolTalk サービスが、オブジェクト指向のメッセージを配信するときに使用するアドレス指定情報を提供します。ユーザーが持つ otype の数とそれらの otype が表すものは、ユーザーのアプリケーションの性質によって異なります。たとえば、ワープロ用のアプリケーションの otype は文字、単語、パラグラフ、文書などになり、図編集用のアプリケーションの otype はノード、円弧、注釈ボックス、ダイアグラムなどになります。

otype は、オブジェクト型識別子 (otid) で始まります。otid の後には、次の項目が続きます。

  1. オプションの開始文字列 — ToolTalk は、必要に応じてこのコマンドを実行し、プログラムを実行するプロセスを起動します。

  2. シグニチャ — その型のオブジェクトにアドレス指定できるメッセージを定義するコード (つまり、その型のオブジェクトに対して呼び出せる動作)

シグニチャ

「シグニチャ」は、その型のオブジェクトにアドレス指定できるメッセージを定義します。シグニチャは、矢印 (=>) によって 2 つの部分に分けられます。シグニチャの前半部分は、着信メッセージの照合基準を定義します。シグニチャの後半部分は、シグニチャの前半部分に一致した各メッセージに ToolTalk サービスが追加する受信側の値を定義します。これらの値は、操作およびメッセージの配信範囲と処置を実行するプログラムの ptid を指定します。

otype ファイルの作成

次のコード例は、otype ファイルの構文を示しています。

otype	::=	obj_header	'{' objbody* '}' [';']
obj_header	::=	'otype' otid [':' otid+]
objbody	::=	`observe:' osignature*
	|	`handle:' osignature*
		`handle_push:' osignature*
		`handle_rotate:' osignature*
osignature	::=	op args [contextdcl] [rhs][inherit] `;'
rhs	::=	[`=>' ptid [scope]]
		[`start'][`queue']
		[`opnum='number]
inherit	::=	`from' otid
args	::=	`(` argspec {, argspec}* `)'
	|	`(void)'
	|	`()'
contextdcl	::=	`context' `(` identifier {, identifier}* `)' `;'
argspec	::=	mode type name
mode	::=	`in' | `out' | `inout'
type	::=	identifier
name	::=	identifier
otid	::=	identifier
ptid	::=	identifier

obj_Header 情報

otid — 「オブジェクト型識別子」。オブジェクト型を識別します。otid は、導入システムごとに一意でなければなりません。この識別子は、インストール後は変更できません。したがって、選択する個々の名前は一意でなければなりません。たとえば、otype を実行するツールの ptid で始めることができます。otid には、64 文字以内という制限があり、予約済み識別子 (ptype、otype、start、opnum、queue、file、session、observe、または handle) は使用できません。

osignature 情報

otype の定義のオブジェクト本体の部分は、アプリケーションが監視および処理の対象とするオブジェクトに関する、メッセージの osignature を記述したものです。

op — 操作名。この名前は、メッセージの操作属性と照合されます。


注 –

ptype と otype の両方にメッセージシグニチャを指定する場合は、それぞれに一意の操作名を使用します。たとえば、ptype と otype の両方に表示操作は指定できません。


args — 操作のための引数。args リストが void の場合、シグニチャは引数のないメッセージだけに一致します。args リストが空で (つまり ()) である場合は、シグニチャは引数とは無関係に一致します。

contextdcl — コンテキスト名。この名前の付いたコンテキストを持つパターンがシグニチャから生成される場合、パターンは空の値リストを持ちます。

ptid — この型のオブジェクトを管理するアプリケーションのプロセス型識別子

opnum — 指定された数をメッセージの opnum 属性に書き込み、メッセージと一致したシグニチャを識別できるようにします。

メッセージがシグニチャと一致するとき、シグニチャの opnum がメッセージに組み込まれます。これでアプリケーションは、tt_message_opnum 呼び出しによって opnum を検索できます。シグニチャごとに固有の opnum を指定すると、どのシグニチャがメッセージと一致したかを判定できます。

tt_otype_opnum_callback_add 呼び出しを使用すれば、opnum にコールバックルーチンを接続できます。メッセージが一致すると、ToolTalk サービスは、その opnum に接続されたコールバックをすべて調べ、それらを起動します。

inherit — otype は、操作を基本の型から引き継げる引き継ぎ階層を形成します。ToolTalk サービスでは otype を定義する場合、引き継いだすべての操作と引き継ぎ元の otype を明示的に指定しなければなりません。この明示的な指定によって、後からの変更 (階層に新しいレベルを追加することや、基本の型に新しい操作を追加することなど) が、otype の動作に予想外の影響を与えるのを防止できます。

scope — このパターン属性は、メッセージの配信範囲属性と照合されます。配信範囲は矢印の右端にあり、メッセージのディスパッチのときに ToolTalk サービスが書き込みます。これは otype を定義するときに、属性を指定できることを意味します。つまり、メッセージの送信側は、メッセージの配信方法を理解していなくてもかまいません。

osignature 処理情報

start — osignature がメッセージに一致しても、この otype を持つ実行中プロセスの中にメッセージに一致したパターンを持つものがない場合は、この otype のプロセスを起動します。

queue — osignature がメッセージに一致しても、この otype を持つ実行中プロセスの中に、メッセージに一致したパターンを持つものがない場合は、この otype のプロセスがメッセージに一致したパターンを持つものを登録するまで、メッセージを待ち行列に入れます。

次に otype ファイルの例を示します。

#include "Sun_EditDemo_opnums.h"

otype Sun_EditDemo_object {
	 handle:
	 /* hilite object given by objid, starts an editor if necessary */
	 hilite_obj(in string objid)
		=> Sun_EditDemo session start opnum=Sun_EditDemo_HILITE_OBJ;
};

Sun_EditDemo_opnums.h ファイルは、edit.c が使用するすべての opnum のシンボリック定義を定義します。これによって、edit.types ファイルと edit.c ファイルは同じ定義を共有できます。

型情報のインストール

ToolTalk 型データベースを使用すると、送信処理を実行するホスト、受信処理を実行するホスト、およびプロセスが結合しているセッションを実行しているホストが、ptype と otype の情報を利用できます。

ToolTalk 型データベースに型情報を格納し、ToolTalk サービスが利用できるようにするには、ToolTalk 型コンパイラの tt_type_comp で型ファイルをコンパイルします。このコンパイラは、型情報の ToolTalk 型定義を作成し、ToolTalk 型データベースに格納します。詳細は、第 5 章「アプリケーション情報の管理」を参照してください。

今回のバージョンの ToolTalk サービスには、現在動作中の ttsession にコンパイル済み ToolTalk 型ファイルを併合する次のような関数があります。

 tt_session_types_load(current_session, compiled_types_file)

current_session は現在のデフォルト ToolTalk セッション、compiled_types_file はコンパイル済み ToolTalk 型ファイルの名称です。この関数は新しい型は追加し、同じ名前を持つ型が既にあれば置き換えます。他の既存の型は元のままです。


注意 – 注意 –

tt_session_types_load() の動作は、ttsession(1) と ttsession_file(4) の両方の引数によって制御されます。tt_session_types_load( ) を使用する前に、これらのマニュアルページを参照してください。


既存のプロセス型の確認

ToolTalk サービスには、指定された ptype が、現在のセッションにすでに登録されているかどうかを確認する簡単な関数があります。

 tt_ptype_exists(const char *ptid)

ptidは、登録されているかどうかを確認するセッションの識別子です。

プロセス型の宣言

型情報は、(アプリケーションのインストール時に) 一度しか指定しません。したがってアプリケーションは、起動するたびに ptype の宣言だけを行う必要があります。

ptype を宣言するには、アプリケーションの ToolTalk 初期化ルーチンで tt_ptype_declare を使用します。ToolTalk サービスは、ptype と指定した ptype を参照する otype に記述されたメッセージパターンを作成します。

ptype を宣言すると作成されるメッセージパターンは、アプリケーションが ToolTalk セッションを終了するまでメモリーに存在します。


注 –

ptype 情報を宣言するときに作成されるメッセージパターンは、tt_pattern_unregister で登録を解除できません。ただし、tt_ptype_undeclare を使用すると、これらのパターンの登録を解除できます。


次にプログラム初期設定時に ptype を登録する方法を示します。

/*
 * Initialize our ToolTalk environment.
 */
int
edit_init_tt()
{
        int     mark;
        char    *procid = tt_open();
        int     ttfd;
        void    edit_receive_tt_message();

        mark = tt_mark();

        if (tt_pointer_error(procid) != TT_OK) {
                return 0;
        }
        if (tt_ptype_declare(“Sun_EditDemo”) != TT_OK) {
                fprintf(stderr,”Sun_EditDemo is not an installed ptype.\n”);
                return 0;
        }
        ttfd = tt_fd();
        tt_session_join(tt_default_session());
        notify_set_input_func(edit_ui_base_window,
                              (Notify_func)edit_receive_tt_message,
                              ttfd);

        /*
         * Note that without tt_mark() and tt_release(), the above
         * combination would leak storage -- tt_default_session() returns
         * a copy owned by the application, but since we don't assign the
         * pointer to a variable we could not free it explicitly.
         */

        tt_release(mark);
        return 1;
}

プロセス型の宣言解除

宣言した ptype を宣言解除する必要が生じる場合があります。たとえば、CASE 環境における次のような場合です。

ptype を登録解除するには、tt_ptype_undeclare を使用します。この呼び出しは、tt_ptype_declare と逆の動作をします。つまり、ptype から生成されたすべてのパターンを登録解除します。さらにセッションが保持する、この ptype を持つ有効プロセスのリストからプロセスを削除します。指定した ptype が呼び出し側プロセスによって宣言されていない場合、この呼び出しは TT_ERR_PTYPE の状態を返します。


注意 – 注意 –

tt_type_undeclare を 1 回呼び出すと、プロセスが ptype を宣言した回数に関係なく、ptype は完全に登録解除されます。つまり、ptype の複数の宣言は、1 回の宣言と同じです。


例 10–1 は、宣言した ptype を宣言解除する方法の例です。


例 10–1 ptype の宣言解除

/*

 * Obtain procid
 */
tt_open();

/*

 * Undeclared Ptype

 */
tt_ptype_undeclare(ptype);