Difference between revisions of "LlMessageLinked/ja"

From Second Life Wiki
Jump to navigation Jump to search
m
 
(3 intermediate revisions by one other user not shown)
Line 2: Line 2:
|func_id=164|func_sleep=0.0|func_energy=10.0
|func_id=164|func_sleep=0.0|func_energy=10.0
|func=llMessageLinked|sort=MessageLinked
|func=llMessageLinked|sort=MessageLinked
|p1_type=integer|p1_name=linknum|p1_desc=リンクナンバーあるいはLINK_* フラグ。
|p1_type=integer|p1_name=linknum|p1_desc=リンクナンバーあるいは LINK_* フラグ。どのプリムが link_message を受け取るかをそれで制御します。
|p2_type=integer|p2_name=num
|p2_type=integer|p2_name=num|p2_desc=link_message イベントの 2 番目の引数になります。
|p3_type=string|p3_name=str
|p3_type=string|p3_name=str|p3_desc=link_message イベントの 3 番目の引数になります。
|p4_type=key|p4_name=id
|p4_type=key|p4_name=id|p4_desc=link_message イベントの 4 番目の引数になります。
|func_desc=グループ内の'''num''''''str'''そして'''id'''パラメータ、又は'''linknum'''のリンクと[[link_message/ja|link_message]]で作動します。
|func_desc=この関数は、同一オブジェクトのスクリプトに情報のやりとりをさせるためにあります。これは '''linknum''' で指定されたプリムの中の全てのスクリプトで {{LSLG/ja|link_message}} イベントを同じ引数 '''num''' '''str''' '''id''' で発生させます。
|func_footer='''id'''を2つ目のstringフィールドのように使うことができます(LSLでは、[[key/ja|key]]は慣用的演算子として[[string/ja|string]]のように実行されます)。stringとkey間での型変更は、含まれているデータへの影響はありません。
|func_footer='''id''' を第二の string フィールドのように使うことができます{{Footnote|LSL では {{LSLG/ja|key}} 型が {{LSLG/ja|string}} として実装されています (しかし操作と制約は異なります) 。string と key の間の {{LSLG/ja|typecast|型変換}} は中に入っているデータに何の影響も及ぼしません。}} 。 '''str''' と '''id''' のサイズはスクリプトのメモリが許す限り無制限です。
|constants
|constants
|func_footnote
|func_footnote
|return_text
|return_text
|spec
|spec
|caveats=*スクリプトは、'''linknum''''''LINK_SET'''もしくは'''LINK_THIS'''で設定されている場合に自身にリンクされたメッセージを聞くことができます。これは無限ループの可能性をもちます(よくないことです)。どんなメッセージが平行してハンドル、通過するのかよく注意しましょう。
|caveats=*'''linknum''' がスクリプトの入っているプリムを指しているのであれば、スクリプトはそれ自身の発したリンクメッセージを拾うことができます {{Footnote|スクリプトにそれ自身を対称にさせる方法は 4 つあります: {{LSLG/ja|llGetLinkNumber|それ自身のリンク番号}} 、{{LSLG/ja|LINK_THIS}} 、{{LSLG/ja|LINK_SET}} 、{{LSLG/ja|LINK_ALL_CHILDREN}} (プリムが子プリムである場合) です。}} 。これは無限ループ (よくないこと) を発生させる可能性があります。メッセージの扱い方と渡し方によく気をつけてください。
*幾つかのユーザはメッセージを、LINK_SETとLINK_ALL_OTHERSとLINK_ALL_CHILDRENを使用している異なるプリム内で、大きなリンク番号を受け取っているスクリプトに送っているときに、リンクされたメッセージが失敗する原因を留意していました(例えば、全てのプリムがメッセージを受け取らない、など)。もしこの問題に遭遇している場合、回避方法は単一プリム内のスクリプトを全ての子プリムに置くことであり、プリム内に前もって存在していたスクリプトを編集して、llSetLinkPrimitiveParamsのような対象とされる関数を使用し、彼らのアドレスへ単一のリンクメッセージを使います。[[User:Void Singer|Void Singer]]
* llMessageLinked で {{LSLG/ja|llSleep|スリープ中}} 、{{LSLG/ja|LSL Delay|遅延している}} 、{{LSLG/ja|lag|ラグにはまっている}} スクリプトに送られたメッセージは遅延が解消するまでキューに蓄積されます。このイベントキューは 64 イベントまでもつことができます。
|examples=<lsl>default{ // assumptions // object name: LSLWiki // script name: _lslwiki
** イベントが受信され、キューがいっぱいの場合は、イベントは警告を出さずに失われます。
     state_entry() {
** link_message を大量のスクリプトにいっせいに送信するのは避けましょう。ラグを発生させる原因になるからです。これは複数プリムを指す LINK_* フラグを使っている時によく起こり、スクリプトの実行を遅くしたり止めたりすることもあります。
** link_message を送信先が処理できるスピードよりも早く送信するのは避けましょう。これをやると、イベントキューがいっぱいになって、後続のメッセージが警告もなく破棄される危険があります。
* スクリプトの {{LSLG/ja|state}} が変わると、保留中のイベントは全て削除されます。キューに蓄積された link_message もです。
* '''link_num''' がリンク番号として正しくない場合、関数はエラーを出さずに失敗します。
* '''str''' '''id''' がスクリプトが link_message イベントの結果をキャッシュするのに使用可能なメモリ量を超えると、スクリプトは [[LSL_Errors/ja#Script_run-time_error:_Stack-Heap_Collision|Stack-Heap Collision]] でクラッシュします。
|examples=<source lang="lsl2">default
{  
    // 前提 // オブジェクトの名前: LSLWiki // スクリプトの名前: _lslwiki
     state_entry()  
    {
         llMessageLinked(LINK_THIS, 0, llGetScriptName(), "");
         llMessageLinked(LINK_THIS, 0, llGetScriptName(), "");
     }
     }


     link_message(integer sender_num, integer num, string msg, key id) {
     link_message(integer sender_num, integer num, string msg, key id)  
    {
         llOwnerSay(msg);
         llOwnerSay(msg);
         // the owner of object LSLWiki will hear
         // LSLWiki のオーナーには次のように聞こえます
         // LSLWiki:_lslwiki
         // LSLWiki:_lslwiki
     }     
     }     
}</lsl>
}</source>
|helpers=<lsl>default
 
{ // Quick and dirty debugging link_messages
=== 無限ループ ===
     link_message(integer sender_num, integer num, string msg, key id) {
 
<source lang="lsl2">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)); // なんという数字の羅列でしょう!
    }
}</source>
|helpers=<source lang="lsl2">default
{  
    // link_message のざっくりとしたデバッグ
     link_message(integer sender_num, integer num, string msg, key id)  
    {
         llSay(DEBUG_CHANNEL, llList2CSV([sender_num, num, msg, id]));
         llSay(DEBUG_CHANNEL, llList2CSV([sender_num, num, msg, id]));
     }
     }
}</lsl>
}</source>
<lsl>// This is just an example script, you shouldn't handle link message within single script this way.
<source lang="lsl2">// これは単なるサンプルスクリプトです。1 つのスクリプトの中でこのようにメッセージを処理しないようにしましょう。


default{ // To propagate an unlimted number of arguments of any type.
default
// Presumed, the separator string isn't used in any source string!
{  
     state_entry() {  
    // いつでも無限の数の引数を繁殖させるスクリプトです。
    // セパレータ文字列が元の文字列で使われていないことが前提です!
     state_entry()  
    {
         list my_list = [1, 2.0, "a string", <1, 2, 3>, <1, 2, 3, 4>, llGetOwner()];   
         list my_list = [1, 2.0, "a string", <1, 2, 3>, <1, 2, 3, 4>, llGetOwner()];   
         string list_parameter = llDumpList2String(my_list, "|"); // Typecast list to a string
         string list_parameter = llDumpList2String(my_list, "|"); // リストを文字列に変換
         llMessageLinked(LINK_THIS, 0, list_parameter, "")
         llMessageLinked(LINK_THIS, 0, list_parameter, "")
     }
     }


     link_message(integer sender_num, integer num, string list_argument, key id) {
     link_message(integer sender_num, integer num, string list_argument, key id)  
         list re_list = llParseString2List(list_argument, ["|"], []); // Typecast string back to a list
    {
     }  
         list re_list = llParseString2List(list_argument, ["|"], []); // 文字列をリストに逆変換
}</lsl>
     }
}</source>
|also_header
|also_header
|also_events={{LSL DefineRow||[[link_message/ja|link_message]]|}}
|also_events={{LSL DefineRow||{{LSLG/ja|link_message}}|}}
|also_functions
|also_functions
|also_articles
|also_articles
|also_footer
|also_footer
|notes=*単一プリムのオブジェクト内でllMessageLinkedを使うのは、スクリプトの協同と動作の同期の間で、機能性が分散するいくつかのLSLの限界を和らげる開発の支えになります。これを行なう時は、典型的な上記のような無限ループを作らないように十分に注意しましょう。
|notes=*単一プリムのオブジェクト内で llMessageLinked を使うと、一緒に動いているスクリプト間と同期しているアクション間の機能を壊すことで、開発者が LSL の制約を超えることができます。これを行うときは、上で述べた無限ループを作成しないよう、充分に注意しましょう。
*strとidのサイズは有効なスクリプトのメモリ量を限界とする、と思います。--[[User:RJ Thibaud|RJ Thibaud]] 13:27, 23 December 2007 (PST)
*LINK_SET 、LINK_ALL_OTHERS 、LINK_ALL_CHILDREN を使って、メッセージを異なるプリムにある大量の受信スクリプトに送信するときに、たまにリンクメッセージに失敗することがあると指摘するユーザもいます。この問題に遭遇したら、回避策は、全ての子プリムのスクリプトを 1 個のプリムに集約し、 {{LSLG/ja|llSetLinkPrimitiveParams}} などのターゲット指定の関数を使い、スクリプトが以前あったプリムを編集することです。 -- {{LSLG|User:Void Singer|Void Singer}}
|cat1=Communications
|cat1=Communications
|cat2=Link
|cat2=Link

Latest revision as of 04:06, 25 February 2016

要約

関数: 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の関連した項目が参考になるかもしれません。