LlMessageLinked/ja

From Second Life Wiki
Jump to navigation Jump to search

要約

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

この関数は、同一オブジェクトのスクリプトに情報のやりとりをさせるためにあります。これは linknum で指定されたプリムの中の全てのスクリプトで link_message イベントを同じ引数 numstrid で発生させます。

• integer linknum リンクナンバーあるいは LINK_* フラグ。どのプリムが link_message を受け取るかをそれで制御します。
• integer num link_message イベントの 2 番目の引数になります。
• string str link_message イベントの 3 番目の引数になります。
• key id link_message イベントの 4 番目の引数になります。

id を第二の string フィールドのように使うことができます[1]strid のサイズはスクリプトのメモリが許す限り無制限です。
フラグ 説明
LINK_ROOT 1 リンクセットの中のルートプリムに送ります
LINK_SET -1 全プリムに送ります
LINK_ALL_OTHERS -2 自分以外の全プリムに送ります
フラグ 説明
LINK_ALL_CHILDREN -3 (ルートプリム以外の全ての)子プリムに送ります
LINK_THIS -4 スクリプトの入った自プリムに送ります

警告

  • linknum がスクリプトの入っているプリムを指しているのであれば、スクリプトはそれ自身の発したリンクメッセージを拾うことができます [2] 。これは無限ループ (よくないこと) を発生させる可能性があります。メッセージの扱い方と渡し方によく気をつけてください。
  • llMessageLinked で スリープ中遅延しているラグにはまっている スクリプトに送られたメッセージは遅延が解消するまでキューに蓄積されます。このイベントキューは 64 イベントまでもつことができます。
    • イベントが受信され、キューがいっぱいの場合は、イベントは警告を出さずに失われます。
    • link_message を大量のスクリプトにいっせいに送信するのは避けましょう。ラグを発生させる原因になるからです。これは複数プリムを指す LINK_* フラグを使っている時によく起こり、スクリプトの実行を遅くしたり止めたりすることもあります。
    • link_message を送信先が処理できるスピードよりも早く送信するのは避けましょう。これをやると、イベントキューがいっぱいになって、後続のメッセージが警告もなく破棄される危険があります。
  • スクリプトの state が変わると、保留中のイベントは全て削除されます。キューに蓄積された link_message もです。
  • link_num がリンク番号として正しくない場合、関数はエラーを出さずに失敗します。
  • strid がスクリプトが link_message イベントの結果をキャッシュするのに使用可能なメモリ量を超えると、スクリプトは Stack-Heap Collision でクラッシュします。
All Issues ~ Search JIRA for related Bugs

サンプル

default
{ 
    // 前提  // オブジェクトの名前: LSLWiki // スクリプトの名前: _lslwiki
    state_entry() 
    {
        llMessageLinked(LINK_THIS, 0, llGetScriptName(), "");
    }

    link_message(integer sender_num, integer num, string msg, key id) 
    {
        llOwnerSay(msg);
        // LSLWiki のオーナーには次のように聞こえます
        // LSLWiki:_lslwiki
    }    
}

無限ループ

Message_Control(integer l, integer n) // Message_Total_Lack_Of_Control
{
    integer r = (++n); // n の値をインクリメントします
    llMessageLinked( l, r, "", ""); // 結果を l に送ります
}

default
{
    state_entry()
    {
        Message_Control(LINK_SET, 0); // オブジェクトの全てのスクリプトに state に入ったことを知らせます
    }
    link_message(integer Sender, integer Number, string String, key Key) // このスクリプトもオブジェクトに入ってます
    {
        Message_Control(Sender, Number); // フィルタ条件はありません
        llOwnerSay(((string)Number)); // なんという数字の羅列でしょう!
    }
}

便利なスニペット

default
{ 
    // link_message のざっくりとしたデバッグ
    link_message(integer sender_num, integer num, string msg, key id) 
    {
        llSay(DEBUG_CHANNEL, llList2CSV([sender_num, num, msg, id]));
    }
}
// これは単なるサンプルスクリプトです。1 つのスクリプトの中でこのようにメッセージを処理しないようにしましょう。

default
{ 
    // いつでも無限の数の引数を繁殖させるスクリプトです。
    // セパレータ文字列が元の文字列で使われていないことが前提です!
    state_entry() 
    {
        list my_list = [1, 2.0, "a string", <1, 2, 3>, <1, 2, 3, 4>, llGetOwner()];  
        string list_parameter = llDumpList2String(my_list, "|");	// リストを文字列に変換
        llMessageLinked(LINK_THIS, 0, list_parameter, "")
    }

    link_message(integer sender_num, integer num, string list_argument, key id) 
    {
        list re_list = llParseString2List(list_argument, ["|"], []);	// 文字列をリストに逆変換
    }
}

注意点

リンク番号

オブジェクトを構成するそれぞれのプリムにはアドレスがあります。それがリンク番号です。オブジェクトの特定のプリムにアクセスするには、そのプリムのリンク番号を知らなければなりません。リンク番号はプリムに振られますが、オブジェクトに座っているアバターにも振られます。

  • オブジェクトが単一のプリムで構成されていて、アバターが座っていないとき、(ルート)プリムのリンク番号は 0 です。
  • しかし、オブジェクトが複数のプリムで構成されていたり、オブジェクトに座っているアバターがいたりすると、ルートプリムのリンク番号は 1 となります。

アバターがオブジェクトに座ると、リンクセットの末尾に追加され、いちばん大きなリンク番号が振られることになります。さらに、アバターがオブジェクトに座っている場合、アバターを立たせないと、プリムのリンク・リンク解除ができません。

プリムやアバターの数え方

オブジェクトのプリムや、プリムに座っているアバターの数を調べるのに、2つの関数があります。

  • llGetNumberOfPrims() - プリムと座っているアバターの数を返します。
  • llGetObjectPrimCount(llGetKey()) - オブジェクトのプリムの数だけを返しますが、アタッチメントとなっている場合は 0 を返します。
integer GetPrimCount() { //常にプリムの数だけを返します。
    if(llGetAttached())//装着されているか?
        return llGetNumberOfPrims();//アバターとプリムの数を返しますが、アタッチメントの上には座れないのでこれでいいです。
    return llGetObjectPrimCount(llGetKey());//プリムの数だけを返しますが、アタッチメントの場合ここは通りません。
}
  • 単一プリムのオブジェクト内で llMessageLinked を使うと、一緒に動いているスクリプト間と同期しているアクション間の機能を壊すことで、開発者が LSL の制約を超えることができます。これを行うときは、上で述べた無限ループを作成しないよう、充分に注意しましょう。
  • LINK_SET 、LINK_ALL_OTHERS 、LINK_ALL_CHILDREN を使って、メッセージを異なるプリムにある大量の受信スクリプトに送信するときに、たまにリンクメッセージに失敗することがあると指摘するユーザもいます。この問題に遭遇したら、回避策は、全ての子プリムのスクリプトを 1 個のプリムに集約し、 llSetLinkPrimitiveParams などのターゲット指定の関数を使い、スクリプトが以前あったプリムを編集することです。 -- Void Singer

関連項目

イベント

•  link_message

関数

•  llGetLinkNumber スクリプトが入っているプリムのリンク番号を取得します。

特記事項

Search JIRA for related Issues

脚注

  1. ^ LSL では key 型が string として実装されています (しかし操作と制約は異なります) 。string と key の間の 型変換 は中に入っているデータに何の影響も及ぼしません。
  2. ^ スクリプトにそれ自身を対称にさせる方法は 4 つあります: それ自身のリンク番号LINK_THISLINK_SETLINK_ALL_CHILDREN (プリムが子プリムである場合) です。

Signature

function void llMessageLinked( integer linknum, integer num, string str, key id );
この翻訳は 原文 と比べて古いですか?間違いがありますか?読みにくいですか?みんなで 修正 していきましょう! (手順はこちら)
この項目はあなたにとって参考にならない項目ですか?もしかしたらLSL Wikiの関連した項目が参考になるかもしれません。