listen


listen(integer channel, string name, key id, string message)

listen()イベントは、llListen()関数で指定された条件にマッチしているチャットメッセージが聞こえた時に発生します。
channelはチャットを拾ったチャンネルを、nameとidは話者の名前とキーを、
そして、メッセージは拾ったメッセージそのものが渡されます。

チャンネル0はパブリックなチャンネルで全てのユーザーが見ることの出来るテキストです。

チャンネル1~2,147,483,648と-1~-2,147,483,648の範囲はプライベートなチャンネルであり、SLクライアントには直接は送信されません。
しかし、スクリプトはそれを聞き取ることが出来ます。

指定したチャンネルの全てのメッセージに対してlisten()イベントを発生させたい場合は、llListen()関数を呼び出す際に条件を何も指定しないでください。

次の例は、listen()イベントで、話者がオブジェクトのオーナーであるかを
idパラメーターを使って判定するためのものです。
Example 1:
default
{
   [[state_entry]]()
   {
       llListen( 0, "", NULL_KEY, "" ); 
   }
   listen( integer channel, string name,
           key id, string message )
   {
       if ( id == llGetOwner() )
       {
           llWhisper( 0, "I hear and obey, master." );
           // interpret message
       }
       else
       {
           llWhisper( 0, "You're not the boss of me." );
           // etc.
       }
   }
}
listen()イベントは、特定のコマンドをチェックするためにメッセージ・パラメーターを検査することにも使うことが出来ます。
次の例では話者が誰であるかは関係なく、コマンドを検査するためのものです。
Example 2:
default
{
   state_entry()
   {
       llListen( 0, "", NULL_KEY, "" ); 
   }
   listen( integer channel, string name,
           key id, string message )
   {
       if ( message == "open sesame" )
       {
           llWhisper( 0, "Welcome!" );
           // open door
       }
       else
       {
           llWhisper( 0, "That's not the magic word." );
           // etc.
       }
   }
}
条件に合わないメッセージを完全に無視したければ、llListen()関数を呼び出す際に厳密な条件を指定するべきです。そうしておけばlisten()イベントはメッセージを受け取っても一切反応しません。
実際、できるだけllListen()関数の使用を控えるべきです。
負荷の掛かっているエリアでは、他愛のないチャットでも、文章の行ごとにListen()イベントを引き起こす原因となるので、スクリプトとSIMのパフォーマンスに影響を与えます。

例1を実現する、さらに好ましいやり方。(例3)

default
{
   state_entry()
   {
       llListen( 0, "", llGetOwner(), "" ); 
   }
   listen( integer channel, string name,
           key id, string message )
   {
       llWhisper( 0, "I hear and obey, master." );
   }
}

スクリプトが複数のチャンネル上のチャットを同時に聞くことができることに注意してください。
(Example 4)
default
{
   state_entry()
   {
       llListen(0,"",llGetOwner(),"");
       llListen(1,"",llGetOwner(),"");
   }
   listen(integer channel, string name,
          key id, string message)
   {
       if (channel == 0)
       {
           llSay(0, "Channel 0.");
       }
       else if (channel == 1)
       {
           llSay(0, "Channel 1.");
       }
   }
}
どのような場合でも、負荷を小さくするために、llListen()関数の呼び出しを必要最小限に維持するようにしてください。
異なるチャンネルに対して多数のリスナーを登録することは有効ですが、
同じチャンネル上の複数のリスナーを設定するためにそれぞれの個別のフィルターを作ってもそれは有効ではありません。
同じチャンネルのフィルターを設定すると以前に指定されたフィルターは上書きされてしまうからです。

上記の文章はもはや正しくありません。
確認して、移動/修正してください。
翻訳者注:これはあくまでWIKIの翻訳であります。
時系列的に考えて、現在の使用は同じチャンネルにおいても
複数のフィルターの指定が可能であると思われます。


Q: 複数のリスナーを指定するのであれば、フィルタを指定せずに、イベントハンドラの中でIFブロックを書き連ねたほうが良いのでしょうか?
A: 複数のリスナーフィルターの使用は、それほど負荷をかけるものではありません。
Q: listen()のイベントのメッセージキューは、どれくらいの長さですか?
A: 後でテストしますが、30個までじゃないかな?それ以降は破棄されるはずだよ。
最終更新:2008年05月02日 09:00