実用的なメッセージのやりとり
前回は、LSLで16KBを超えるプログラミングを行う場合の、基本的になメッセージのやり取りついてお話しました。
今回は、前回お話した通信方法を使って実用的なメッセージのやりとりを行うプログラムの方法についてお話したいと思います。
実用的なというのは、ここでは
- セカンドライフ内のオブジェクト(複数のプリムを組み合わせたモノ。建物や車などはみんなオブジェクト)が複数のプリム(セカンドライフのな型のボックスとかシリンダーとか)で構成されている
- ひとつのプリムに複数のスクリプトがある
- 後で、プリムやスクリプトは拡張されていく可能性がある。
というような状況に対応できるということです。
実用的なメッセージのやりとりのための方針
このようなスクリプトをLSLで美しくつくることは困難ですが、だからといって方針を立てずに作ることは危険です。
そこで、私は、上記の状況を想定したうえでプログラムをするための方針をまとめてみました。
- 方針1 メインの処理は中央集権(1つの開始ポイントから始まる)
LSLでは、複数のスクリプトが同時に開始されます。(少なくとも、どの順番で初期化されるか明示的ではない) したがって、複数の開始ポイントを持つ実装は簡単にできます。複数の開始ポイントをむやみに利用するとどの順番で初期化されるかがあいまいになります。そういった状況の上でメッセージが追加されていくと、メッセージのやり取りの前提を設計することも難しくなります。そこで、ある機能の塊を実現するプリム群の初期化は、一つのスクリプトにメイン処理として記述するのがよいでしょう。メッセージをやり取りしない独立したプリム群が複数ある場合には、群ごとにメインの処理を決めてもよいと思います。

- 方針2 メッセージの通信は階層的
ここで通信は階層的といっているのは、メインの処理を行うスクリプトを親として、ツリー上にスクリプトを配置して、ツリーの枝に沿って通信を行うということです。この方法だと、メッセージの流れをメインの処理でハンドリングしやすくなります。もちろん、子のスクリプトが孫から来たメッセージをすべて親のスクリプトに返す必要はありません。必要に応じて、子は別の孫にメッセージを送ることもあるでしょう。通信を階層的にしておく理由の一つは、デバッグ時にメッセージの流れを捕まえやすくするためです。もしも、階層的ではなく、全スクリプトがお互いに通信を行った場合、通信の組み合わせは無数にできることになります。そのような状態を考慮してデバッグすることは不可能に近いでしょう。
- 方針3 一つのスクリプトは1機能
スクリプトを1機能にする理由は、モジュール化という観点もありますが、LSLではオブジェクト指向的な実装は難しく、あまりそういった指標で問題をとらえることは難しいでしょう。どちらかというとメモリ対策として、この方針は存在しています。たとえば、自分のプリム内にメッセージを送信した場合、そのプリム内のスクリプトは、メッセージを受け取ることになります。これは、そのメッセージを必要としていないスクリプトのメッセージを一度はメモリに展開するということです。したがって、ひとつのスクリプトには可能な限り最少単位の機能を書いておきメッセージを受け取るスペースを確保すべきでしょう。 - 方針4 一つのメッセージは短く
これも方針3と同じ理由です。特にLINK_THISを宛先とする場合よりもLINK_SETを宛先とするメッセージについて気を使う必要があります。

- 方針5 プリムの制御が必要ないスクリプトは、親と同じプリムにまとめる。
親と同じプリムにまとめることで、LINK_THISでメッセージを送ることができます。そうすることでメッセージを受信処理するスクリプトを減らすことができるためです。
方針の例外
また、LSLの制約から、上記のルールを厳密に守ることは難しいため、次のような例外的な対応は行ってもよいと思います。
- 各プリムの制御(テクスチャの張り替え、クリックのハンドリング等)のための初期化は分散化するこれは、テクスチャの張り替えやクリックのハンドリングのイベントは、そのプリムに入っているスクリプトからしか実施できないからです。
- 大きなメモリを必要とするデータを持つスクリプトは、階層的でなく直接的に他のスクリプトと通信するこれは、階層的な通信をすることで、無駄にデータコピーが発生するからです。また階層をまたぐことによって、メモリも多く消費してしまいます。
- リアルタイム性のあるイベントが必要な場合には、階層を飛ばした通信をするメッセージを送る場合、メッセージはただちに送れない場合があり得ます。複数の階層を通ることによって少なからず処理に遅延が発生します。また、階層的に通信をする場合、メッセージの伝わる順番等に問題が発生する場合もあるかと思います。そういったことを回避する意味で、例外的に階層を飛ばした通信をすることを許す場合があります。ただ、方針を骨抜きにしないためにも、通常そういった機能は全体で共通化するべきものに限るべきです。
さて、この方針についてご覧になった方はどう思われたでしょうか。この方針は、現時点までのノウハウから考えているものですが、私としては満足していません。今後、よりよい方針を作ることができたらとLSLに取り組んでいます。LSLをされている方は、よりより指針を考えてみてはどうでしょうか。