オブジェクト間の情報通信

SLをSLたらしめているのがオブジェクトの存在です。
このオブジェクトが動的に働くことで、他の言語にはないLSLの面白さがあると言っていいでしょう。
オブジェクトは単体でも色々とできますが、オブジェクト同士を通信で相互に動かすと、さらに面白さが広がります。

イベント

listen(integer channel, string name, key id, string message)
{
    内容;
}

チャットを聞き取った時に発動します。

引数:
integer channel
聞き取ったチャンネルが入ってきます。
string name
発信元の名前が入ってきます。
key id
発信元のUUIDが入ってきます。
string message
聞き取った文字列が入ってきます。

default
{
    listen(integer channel, string name, key id, string message)
    {
        llSay(0, message);
    }
}

基本的に、聞き取った内容を利用する目的で設置するイベントハンドラなので、変数messageを他の関数に引数として渡すことになります。
channel、name、id、などは、分岐条件としてif文で区別するのに使います。
複数のllListenを聞き分けるなら、普通はchannelを調べることになるでしょう。
Listenイベントは頻繁に発生する可能性があるため、設定次第ではサーバーパワーを著しく消耗し、ラグの原因になる可能性があります。
設定には十分の配慮がいるでしょう


link_message(integer sender_num, integer num, string str, key id)
{
    内容;
}

リンクされたプリム同士で通信を行った時に発動します。

引数:
integer sender_num
発信元のプリムナンバーが入ってきます。
integer num
受信した整数値が入ってきます。
string str
受信した文字列が入ってきます。
key id
受信したUUIDが入ってきます。

default
{
    link_message(integer sender_num, integer num, string str, key id)
    {
        llSay(0, (string)sender_num + "番プリムから" + (string)num + "," + 
	str + "," + (string)id + "を受け取りました");
    }
}

Listenがリンクされていない対象に通信をするのに対し、リンクされたプリム同士で通信を行うことができます。
Listenに比べると高速で負荷が少なく、通信内容も整数、文字列、UUIDを個別に送れるのが魅力です。
うまく扱うことで、複雑なオブジェクトを器用に扱うことができるでしょう。


関数

integer llListen(integer channel, string name, key id, string msg);

チャットを聞き取る設定を行います。

戻り値:
integer 変数
llListenの管理番号を変数で指定します。
これにより、複数のllListenを同時に動かすことができます。
省略ができます。

引数:
integer
聞き取るチャンネルを整数で指定します。
string
聞き取る対象の名前を指定します。
全てが対象の時は「""」と書きます。
key id
聞き取る対象のUUIDを指定します。
全てが対象の時は「NULL_KEY」と書きます。
string msg
聞き取る文字列を指定します。
全て聞き取る時は「""」と書きます。

default
{
    state_entry()
    {
        integer handle = llListen(0, "",llGetOwner(), "");
    }
}

Listenイベントを有効にするために設定を行う関数です。
0番チャンネルで全てを対象にすると、周囲で聞き取った全ての通常チャットが対象になるため、サーバーの負荷になります。
フィルターを使うことで影響は微々たるものになります。
商品としてllListenを使う場合、固定のチャンネルでは混信する恐れがあります。
オーナーが使うものはオーナーのUUIDでフィルターをし、複数の人が使うものはチャンネルをランダム可する等の工夫が必要です。
llListenlistenは必ず組みで使わなければ意味がありませんが、途中でstateを切り替えてしまうと、情報がそこで遮断されてしまうために全く働きません。
stateを切り替える前には、確実にリッスンをOFFにするか終了させておく必要があるので注意してください


llListenControl(integer number, integer active);

llListenのON/OFFを切り替えます。

戻り値:
無し

引数:
integer number
llListenを設定した時の戻り値の変数を書きます。
integer active
ON/OFFの指定をします。
指定は定数で行い、TRUEではON、FALSEではOFFになります。

integer select;
integer handle;

default
{
    state_entry()
    {
        handle = llListen(0, "", llGetOwner(), "");
    }

    touch_start(integer total_number)
    {
        if(select == 0)
        {
            llListenControl(handle, TRUE);
            select = 1;
        }
        else if(select == 1)
        {
            llListenControl(handle, FALSE);
            select = 0;
        }
    }
}

llListenを常に稼動させておくとサーバーの負荷になるため、必要の無い時は切っておくことが大切です。
llListenControlは一時的にON/OFFを切り替えて機能を制御する方法で、頻繁に切り替えが必要な時や、チャンネルを固定させておきたい時に使うものです。


llListenRemove(integer number);

llListenを削除します。

戻り値:
無し

引数:
integer number
llListenを設定した時の戻り値の変数を書きます。

integer handle;

default
{
    state_entry()
    {
        handle = llListen(0, "", llGetOwner(), "");
    }

    touch_start(integer total_number)
    {
        llListenRemove(handle);
    }
}

llListenControlとは違い、llListenを削除します。
あまり頻繁にON/OFFをしない時はこちらがいいでしょう。
また、設定できるllListenの数には限りがあるので、チャンネルを変えたい時にもこちらを使います。
再度、リッスンが必要な時は、またllListenを設定し直します。


llMessageLinked(integer linknum, integer num, string str, key id);

リンクしているプリムに通信を送ります。

戻り値:
無し

引数:
integer linknum
送信するプリムナンバーを指定します。
プリム単体は0、リンクオブジェクトはルートプリムが1となり、最初に選択した順に向かってナンバーが大きくなっていきます。
そのほかに、定数を使った指定もあります。

LINK_SET		全てのプリム
LINK_ROOT		ルートプリムのみ
LINK_ALL_CHILDREN	子プリム全て
LINK_THIS		このプリムのみ
LINK_ALL_OTHERS	このプリム以外全て
integer num
送信する整数を書きます。
string str
送信する文字列を書きます。
key id
送信するUUIDを書きます

default
{
    state_entry()
    {
        llMessageLinked(LINK_SET, 0, "message", NULL_KEY);
    }
}

リンクされたプリムを複雑に制御するために必須の関数です。
だいたいは文字列で命令となるキーワードを送る場合が多いですが、時に小数やベクターやローテーションを送りたい場合もあります。
その時は、いったん型変換をして文字列として送ることになります。
llListenとは違い、何も送らない時はイベントが発生しないため、ON/OFFの切り替えが必要ありません。


リッスンスクリプト サンプル

integer handle;

default
{
    touch_start(integer total_number)
    {
        handle = llListen(0, "",NULL_KEY, "");
        llSetTimerEvent(20.0);
    }

    listen(integer channel, string name, key id, string message)
    {
        llSay(0, message);
        llSetTimerEvent(0.0);
        llListenRemove(handle);
    }

    timer()
    {
        llSetTimerEvent(0.0);
        llListenRemove(handle);
    }
}

タッチをすると周囲のチャットを拾ってオウム返しをするスクリプトです。
何も聞けなかった場合は20秒でリッスンを閉じています。


リンクオブジェクト通信 サンプル ルートプリム

default
{
    touch_start(integer total_number)
    {
        llMessageLinked(LINK_SET, 0, "リンク通信送信", NULL_KEY);
    }
}

リンクオブジェクト通信 サンプル 子プリム

default
{
    link_message(integer sender_num, integer num, string str, key id)
    {
        llSay(0, str);
    }
}

タッチをすると親から子へ通信されて子プリムがしゃべるスクリプトです。