
AVS Technical Report -Volume6,Number1 May,1999-
AVS/Express は、あるデータ処理機能を持つオブジェクトとそれらのオブジェクトを管理するオブジェクト・マネージャーから構成されています。各オブジェクトは、V という言語によって定義されています。
この V言語は AVS/Express のあらゆるところで使われており、オブジェクトだけでなく AVS/Express 本体も V言語で作成されています。
これまでの Technical Report では V言語を用いた機能を紹介してきましたが、今回は V言語そのものについて紹介します。
V言語とは、AVS/Express のカーネルであるオブジェクト・マネージャーをコントロールすることができる中間言語です。オブジェクトやネットワークエディタ、ライブラリなどを定義する Vファイルは、以下のディレクトリにあります。
<AVS/Express インストールディレクトリ>/v/
AVS/Express は起動時にこれらのファイルを読み込み、AVS/Express 自身を構築します。
V言語は、以下の 3つの要素で構成されます。
| Vステートメント | ネットワークエディタ上の基本操作を行うための Vコードです。オブジェクトの作成や変更、接続/切断/消去などを行います。 |
|---|---|
| Vコマンド | アプリケーションに対して実行するコマンドです。オブジェクトや Vファイル、アプリケーションの情報入手、実行制御などを行います。 |
| V組み込み関数 | 数値演算や論理演算などを行います。 |
作成した可視化ネットワーク(アプリケーション)の保存を行う場合も V言語で記述されたアスキーファイルとして保存されます。このファイルを Vファイル読んでいます。
V言語はテキストタイプのインタプリタ言語です。
V言語を用いるとネットワークエディタ上で行うアプリケーションの構築やモジュールの操作をインタラクティブに行うことが可能になります。この操作は、VCP(V Command Processor) または ネットワークエディタ上のモジュールから行うことができます。
VCP とは、アプリケーションの構築やデバッグ等の Vコマンドを受け付けるための AVS/Expressインターフェースです。ネットワークエディタとは違い、GUI を持たないテキストベースのインターフェースです。
UNIX版の場合は AVS/Expressを実行したウインドウが、Windows版の場合は AVS/Express起動後に表示される AVS/Express Consoleウインドウが VCP ウインドウです。

図1 UNIX版 VCPウインドウ

図2 Windows版 VCPウインドウ
VCPウインドウには、現在のアプリケーションの最上位階層である Root オブジェクトが表示されています。
OM(Root) ->
"->" の後に Vコマンドを入力します。Vコマンドの実行はカレントの階層に対して行われます。そのため Vコマンドを実行する前に、適切な階層に移動することが必要です。
AVS/Expresシステムは図3のような階層構造になっています。
ネットワークエディタやライブラリに登録されているモジュールなど、すべては AVS/Express の Root 配下の階層に存在します。
AVS/Express Vizを起動したときにデフォルトで現れる MultiWindowApp の位置を図3で確認すると、Root の下にある Applications 配下にあります。
この MultiWindowApp の存在する階層(パス)をAVS/Expressでは以下のように表現します。
Root.Applications.MultiWindowApp
この表記はV言語、またはAVS/Expressのモジュールプログラミングにおいても使用します。
VCPを利用してこの階層を確認してみましょう。
OM(Root) -> $list
$list コマンドはカレントオブジェクト配下にあるオブジェクトのリストを出力する Vコマンドです。
OM(Root) -> $list
scheduler Scheduler
group ProcInstances
group+global Applications
list V
"$XP_PATH<0>/v/proc.v" ProcTemplates
"$XP_PATH<0>/v/templ.v" Templates
link UIdata
library Libraries
NEnetworkEditor NetworkEditor
OM(Root) ->
Applicationsオブジェクトの下に移動してみましょう。
OM(Root) -> Applications {
OM(Applications) -> $list
APPS.MultiWindowApp MultiWindowApp
移動先のオブジェクトを指定し、"{" を付けて改行します。
Applications オブジェクト配下に MultiWindowApp があることを確認できます。
同様に、MultiWindowApp に移動してオブジェクトリストを表示して下さい。以下のような二つのオブジェクトがあることを確認できます。
OM(MultiWindowApp) -> $list
AU.MultiWindowApp.UI UI
GDM.Uviewer Uviewer
OM(MultiWindowApp) ->
上の階層に戻るには "};" と入力します。
OM(MultiWindowApp) -> };
OM(Applicactions) ->
MultiWindowApp へ移動します。
int型オブジェクト(名前をAとする)を配置しましょう。
OM(MultiWindowApp) -> int A;

図4 int Aの配置
オブジェクトを定義する場合は、最後にセミコロン ";" を付けることを忘れないでください。
MultiWindowAppのネットワークエディタ上に A という名前のオブジェクトが配置されたのを確認して下さい。
オブジェクト A に値を設定します。
OM(MultiWindowApp) -> A = 100;
int型オブジェクト B を配置しましょう。
OM(MultiWindowApp) -> int B;

図5 int Bの配置
オブジェクトの接続には、「代入」と「参照」の二通りがあります。
| 代入 |
参照 |
|---|---|
| 「代入」の場合は以下のように定義します。
OM(MultiWindowApp) -> B = A; ![]() 図6 接続(代入) この値は A の値を変更しても固定になります。 |
「参照」の場合は以下のように定義します。
OM(MultiWindowApp) -> B => A; ![]() 図7 接続(参照) ここで A の値を以下のように変更すると B の値も変更されます。 OM(MultiWindowApp) -> A = 200; ![]() 図8 接続(検証) |
オブジェクト B と A の参照関係を切断するには、以下のように定義します。
OM(MultiWindowApp) -> B =>;

図9 切断
インスタンスされているオブジェクトを消去してみましょう。
OM(MultiWindowApp) -> -A;
OM(MultiWindowApp) -> -B;
以下のVコマンドを実行すると配列のオブジェクトをインスタンスすることができます。
OM(MultiWindowApp) -> int A[6];
OM(MultiWindowApp) -> int B[2][3];

図10 配列オブジェクト
インスタンス時に値を設定することも可能です。
OM(MultiWindowApp) -> int A[6]={0,1,2,3,4,5};
配列 A の4番目の要素を参照する場合は以下のようにします。
OM(MultiWindowApp) -> int C=>A[3];

図11 配列オブジェクトの参照
複数のプリミティブ・オブジェクトをグループ・オブジェクトの中に入れ、1つのオブジェクトとして扱うことが可能になります。AVS/Express のフィールドデータはグループ・オブジェクトの一例です。
以下のようにするとグループ・オブジェクト person を作成することができます。
OM(MultiWindowApp) -> group person{
OM(person) -> int No;
OM(person) -> string name;
OM(person) -> int age;
OM(person) -> };

図12 グループ・オブジェクト
No, name, age オブジェクトは person 配下にあるため、オブジェクト person のサブオブジェクトと呼ばれます。MultiWindowApp の階層にあるオブジェクト D が person オブジェクトのサブオブジェクト No を参照する場合には以下のように記述します。
OM(MultiWindowApp) -> int D => person.No;

図13 下位オブジェクトへの参照
"."(ピリオド)が階層の区切りを現します。
カレントの階層より深い(下位)階層を参照する場合には、上記のようにモジュール名をピリオドでつなげて記述しますが、カレントの階層より浅い(上位)階層にあるオブジェクトにアクセスにする場合には、"<-." を使用します。
カレント階層が person で、その一つ上の階層にある E が No を参照する場合は、以下のようになります。
OM(MultiWindowApp) -> int E=25;
OM(MultiWindowApp) -> person{
OM(person) -> No => <-.E;
OM(person) -> };

図14 上位オブジェクトへの参照
V言語では、オブジェクトの継承を行うことが可能です。このときに新たなサブオブジェクトを追加することもできます。
グループ・オブジェクト person を継承し、新たにプリミティブ・オブジェクト address を追加した配列オブジェクト "data person" を作成するには以下のようにします。
OM(MultiWindowApp) -> person data_person[10]{
OM(data_person) -> string address;
OM(data_person) -> };

図15 オブジェクトの継承
(注)オブジェクトの名前に空白を入れる場合は、"_"(アンダーライン) を記述します。ネットワークエディタ上ではアンダーラインは空白で表示されます。
Vコードの中に以下のような演算子や組み込み関数などを記述することができます。
以下に幾つかの例を紹介します。
詳細については デベロッパーズ・ガイド第1部を参照して下さい。
デベロッパーズ・ガイド第1部 [約6.4MB]
まずはじめに、MultiWindowApp 配下にあるオブジェクトを全て削除します。
次に オブジェクト A, B を配置します。
OM(MultiWindowApp) -> int A=100;
OM(MultiWindowApp) -> int B=30;

図16 A,Bオブジェクト
OM(MultiWindowApp) -> int C => A-B;

図17 Cオブジェクト(差)
OM(MultiWindowApp) -> int D => A < B;

図18 Dオブジェクト(比較)
OM(MultiWindowApp) -> float E => sqrt(B);

図19 Eオブジェクト(平方根)
OM(MultiWindowApp) -> string F => E + "= sqrt(" + B + ")";

図20 Fオブジェクト(文字列)
これまではVCPウインドウによる Vコマンドの実行を紹介してきました。
この章ではネットワークエディタ内より Vコマンドを実行する方法について紹介します。
ネットワークエディタ上からVコマンドを実行するために AVS/Expressでは2つのモジュールが標準提供されています。
このモジュールは AVS Technical Report Vol.5, No.1でも紹介しています。
parse_vモジュールはライブラリ Accessories の Utility Modules.General 内にあります。パラメーターtrigger または v_commands が更新されたタイミングで、v_commands内に記述されているVコマンドを実行するモジュールです。
図21は、オブジェクト reset の値が 1 になった時にオブジェクト total と count の値を 0 にするネットワーク(マクロモジュール)です。
パラメーターv_commands には実行する Vコマンドが記述されています。コマンドの終りには必ずセミコロン ";" を付けてください。セミコロンを付けることによって複数の Vコマンドを1行で記述することができます。
パラメーターactive は、値が 0 の場合には parse_v モジュールが動作しないように定義されています。ここでは、reset が 1 以外の時に parse_v が動作しないように定義しています。
Vコマンドが実行される階層はパラメーターrelative で指定します。relative は、2階層上にある macro を指しています。Vコマンドは macro の階層にて実行されます。
load_v_scriptモジュールはライブラリ Accessories の Utility Modules.General 内にあります。パラメーターtrigger または filename が更新された場合に、filename に記述されている絶対パスより Vスクリプトファイルを読み込み、実行するモジュールです。
Vスクリプトファイルを作成します。
以下の 1行をVファイルとして保存します。
string Name = "user1"
例:
UNIX版の場合はファイル名を /tmp/test.v とします。
% vi /tmp/test.v
string Name = "user1"
Windows版の場合はファイル名を C:¥tmp¥text.v とします。
> notepad C:¥tmp¥test.v
string Name = "user1"
Vコマンドが実行される階層はパラメーターrelative で指定します。relative は一つ上の階層 MultiWindowApp を指しています。
パラメーターtrigger に 1 を代入すると /tmp/test.v ファイルが読み込まれ、MultiWindowApp上に オブジェクト Name が生成されます。
今回紹介した V言語は「可視化」に直接、関連する機能ではありませんが、AVS/Express本体を制御できる V言語の仕組みを知ることで可視化の幅が広がると思います。
特に V言語の「参照 ( => )」という機能は、単純でありながら、これを用いると if-else 文のような制御を可視化ネットワークに施すことができるようになります。
例えば、
パラメーターA の値が 0 より大きい場合は パラメーターSTR に "正数" を入力し、
パラメーターA の値が 0 より小さい場合は パラメーターSTR に "負数" を入力する
仕組みを作成すると、以下のようになります。

図23 制御ネットワーク例
V言語を利用する際の注意する点として、以下の2点があります。
STRモジュールの値を参照(=>)ではなく代入(=)にするとSTRに入力した文字列が消えてしまいます。
その状態でアプリケーションを保存すると保存したアプリケーションを読み込んだ際に文字列を入力し直す必要が出てしまいます。
また、作成したアプリケーションの中で用いているモジュール名を変更する場合は、ネットワークエディタからおこなってください。保存したVファイルを開いてモジュール名を変更すると、変更したモジュールを参照している他のモジュールが存在する場合にVファイル読み込み時にエラーになってしまいます。
ネットワークエディタ上で名前の変更を行うと、変更したモジュールを参照している他のモジュールも連動してモジュール名が変更されます。
以上のことを注意して頂きながら、データによってネットワークの接続やパラメーター値の変更を自動化するアプリケーションを構築してみてはいかがでしょうか。
そのような可視化を行う際に、この Technical Report を参考にして頂ければ幸いです。
AVS Support Center, fns-avssup@cs.jp.fujitsu.com