Rice言語のフロントエンド。
RiceManagerクラス
Rice言語のフロントエンドはRiceManagerクラスです。ここでは、RiceManagerクラスの公開メンバについて説明します。
なお、以下の説明では、実装言語としてC#を想定しています。
コンストラクタ
最初に、RiceManagerクラスのインスタンスを取得しなければなりません。
public RiceManager(string filename)
public RiceManager(VirtualMachine vm)
public RiceManager(string filename)
Riceソースファイルへのパスを引数とするコンストラクタです。与えられたソースコードを解析してユーザ定義クラスのプロトタイプを作成して格納します。
例えば
RiceManager manager = new RiceManager("c:\somewhere...\example.cook");
ソースファイルがRice言語の文法として正しい場合はRiceManagerクラスのインスタンスを返します。ソースファイルに文法的な問題がある場合は例外を送出します。
Riceの送出する例外については例外を御覧ください。
RiceManager(string filename)コンストラクタの使用例です。
1: | RiceManager rm = null; |
2: | try { |
3: | rm = new RiceManager("c:\somewhere...\example.cook"); |
4: | } |
5: | catch(Exception e) { |
6: | MessageBox.Show(e.Message); // 例外のメッセージを表示。 |
7: | } |
public RiceManager(VirtualMachine vm)
VirtualMachineクラスを引数とするコンストラクタです。VirtualMachineクラスは解析済みのユーザ定義クラスのプロトタイプを持っています。それを利用してRiceManagerクラスのインスタンスを生成します。
VirtualMachineクラスのインスタンスはRtype派生クラスのメンバ呼び出しで引数として与えられます。VirtualMachineクラスを直接に生成することはできないので、通常のスクリプト実行でこのコンストラクタを使用することはありません。これは、イベント処理やタイマーの実装などの特別な状況で使用されるコンストラクターです。
組み込みクラスの登録
Riceではユーザ定義クラスの他に、C#などで記述されたRtype派生クラスを組み込みクラスとして登録することができます。
public static void AddBuiltIn(string typename, PlainProtoTypeGetter pptg)
public static void RegisterClasses(string directoryPath)
public static void AddBuiltIn(string typename, PlainProtoTypeGetter pptg)
Riceでのクラス名と組み込みクラスを返すデリゲートを登録します。
クラス | 名前 | 説明 |
string | typename | Riceでのクラス名。 |
PlainProtoTypeGetter | pptg | Rtype派生クラスを返すデリゲート。 |
組み込みクラスの登録は、Riceのユーザー定義クラス登録とは異なり、デリゲートを登録します。
デリゲートの定義は以下の通りです。
public delegate Rtype PlainProtoTypeGetter();
組み込みクラスが要求されると、登録されたデリゲートが呼び出されてインスタンスが返されます。
メンバ関数がstaticであることに注意してください。登録された組み込みクラスはRice全体で共有されます。全てのRiceManagerのインスタンスは同じ組み込みクラスの集合を持つことになります。
組み込みクラス"Rexample"があり、以下のメンバがクラスで定義されているとします。
public const string TYPENAME = "example";
public static Rtype InstanceGetter() { return new Rexample(); }
Rexampleの登録は以下の様になります。
RiceManager.AddBuiltIn(Rexample.TYPENAME, Rexample.InstanceGetter);
Rtype派生クラス実装の詳細についてはクラス実装をご覧ください。
public static void RegisterClasses(string directoryPath)
引数で指定されたディレクトリ以下にある全ての組み込みクラスのdllファイルを探索します。
この関数は組み込みクラスの登録を行いません。ディレクトリ階層を巡回して該当するdllファイルを見つけた場合に、その中から決まった関数を呼び出します。
呼び出される関数の中でAddBuiltIn関数を呼び出して組み込みクラスを登録してください。組み込みクラスを使用するために必要な準備があれば、それを行うこともできます。
動的クラスロードの手順、ディレクトリ巡回の詳細については動的クラスロードをご覧ください。
スクリプトの実行
RiceManagerクラスのインスタンスが取得できればRiceスクリプトを実行できます。Riceスクリプトの実行はRiceのユーザ定義クラスのopenメソッドを呼び出すことで開始されます。
public void Run()
public Rtype Invoke(string methodSigneture, Queue<Rtype> argQueue)
public Rtype Invoke(string methodSigneture, Queue<Rtype> argQueue, bool argCheck)
public Rtype Invoke(Rclass rc, string methodname, Queue<Rtype> argqueue)
public Rtype Invoke(Rclass rc, string methodname, Queue<Rtype> argqueue, bool argCheck)
public void Run()
Riceのmainクラスのstart()メソッドを呼び出します。mainクラスやstart()メソッドが定義されていない場合、例外がスローされます。
start()のシグネチャは"open method void start()"です。つまり、start()メソッドは引数を取らず返り値がありません。したがって、Run()関数も引数が無く返り値がありません。
以下はRun()関数の使用例です。
1: | // RiceManager:rmは既に生成されているとする。 |
2: | try { |
3: | rm.Run(); |
4: | } |
5: | catch(Exception e) { |
6: | MessageBox.Show(e.Message); // 例外のメッセージを表示。 |
7: | } |
public Rtype Invoke(string methodSigneture, Queue<Rtype> argQueue)
public Rtype Invoke(string methodSigneture, Queue<Rtype> argQueue, bool argCheck)
これらのメンバ関数を使えば、Riceのmainクラスから任意のopenメソッドを呼び出すことができます。
Riceのmainクラスに"open method int sample(string str, int index)"というメソッドがあるとすると、このメソッドをアプリケーションから呼び出すには次の様にします。
1: | Queue<Rtype> args = new Queue<Rtype>(); |
2: | args.Enqueue(new Rstring("example")); |
3: | args.Enqueue(new Rint(0)); |
4: | Rint result = Invoke("sample(string,int)", args); |
第一引数は呼び出すopenメソッドのシグネチャを指定します。シグネチャはメソッド名の後に括弧で囲んだ引数の型名が続く文字列です。引数が複数ある場合はカンマで区切ります。上記のsampleメソッドならば、シグネチャは"sample(string,int)"となります。シグネチャに該当するopenメソッドが無いときは例外がスローされます。
第二引数はメソッドに渡す引数です。シグネチャの引数の順番で適切なRtype派生クラスのインスタンスをQueue<Rtype>クラスに格納します。
引数が無い場合は括弧の中は空です。例えば"start()"メソッドをInvoke()メンバ関数を使って呼び出す場合の第一引数は"start()"となります。この場合、第二引数は空のQueue<Rtype>を渡します。nullでないことに注意してください。
結果としてRtype派生クラスのインスタンスが返ります。呼び出すメソッドの返り値型がvoidのときはRvoid型が返ります。
一つ目の関数はシグネチャと引数が合致しているかどうかを考慮しません。正しい引数を用意するのはプログラマの責任です。
二つ目の関数はシグネチャと引数が合致しているかどうかのチェックを第三引数で制御できます。第三引数がtrueならチェックを実行します。falseならチェックは実行されません。
チェックの結果、引数が合致しない場合は例外がスローされます。
public Rtype Invoke(Rclass rc, string methodSignature, Queue<Rtype> argqueue)
public Rtype Invoke(Rclass rc, string methodSignature, Queue<Rtype> argqueue, bool argCheck)
これらのメンバ関数を使えば、mainクラス以外のユーザ定義クラスから任意のopenメソッドを呼び出すことができます。
ユーザ定義クラスはRice内部ではRclassクラスとして扱われているので、第一引数で適当なRclassクラスのインスタンスを関数に渡します。このインスタンスから該当するopenメソッドを呼び出します。
第二引数以降は、先のInvoke()関数と同じです。
Rclassクラスは直接生成することが出来ないので、通常のスクリプト実行でこの関数を使用することはありません。これは、イベント処理やタイマーの実装などの特別な状況で使用される関数です。
メソッドの存在確認
Riceスクリプトを実行する前に、mainクラスにopenメソッドが存在するかを確認することができます。
public bool IsOpenMethodOfMain(string signature)
public bool IsOpenMethodOfMain(string signature)
関数の引数に確認したいopenメソッドのシグネチャを渡します。シグネチャはメソッド名の後に括弧で囲んだ引数の型名が続く文字列です。引数が複数ある場合はカンマで区切ります。先のsampleメソッドならば、シグネチャは"sample(string,int)"となります。
シグネチャがmainクラスのopenメソッドとして存在するならばtrueが返ります。そうでなければfalseが返ります。
メッセージ管理
RiceManagerクラスはメッセージ管理のためのメンバ関数を持っています。
public static string GetMessage(string key)
public static string AddMessage(string key, string value)
public static string SetMessage(string key, string value)
public static void SetFromFile(string fileName)
public static void SetFromResource(ResourceManager manager)
public static void SetFromResource(ResourceManager manager, CultureInfo info)
public static bool ContainsKey(string key)
詳細については国際化をご覧ください。
定数のプリセット
Riceでは参照毎に一定値を持つ新しいインスタンスを返す識別子を定数と呼びます。
public static bool RegisterConst(string name, PlainProtoTypeGetter pptg)
public static bool RegisterConst(string name, PlainProtoTypeGetter pptg)
識別子とデリゲートを登録します。メソッド名以外は組み込みクラスの登録と同じです。
定数が参照されると、登録されたデリゲートが呼び出されてインスタンスが返されます。
メンバ関数がstaticであることに注意してください。プリセットされた定数はRice全体で共有されます。全てのRiceManagerのインスタンスは同じ定数の集合を持つことになります。
組み込みクラス"Rexample"があり、以下のメンバがクラスで定義されているとします。
internal static Rexample GetConst() {
return new Rexample("何かの値を設定する。");
}
Rexampleを返す定数"EXAM"をプリセットするには以下の様にします。
RiceManager.RegisterConst("EXAM", Rexample.GetConst);
定数の詳細についてはRiceにおける定数、プリセット定数をご覧ください。