LlUpdateKeyValue/ja

From Second Life Wiki
< LlUpdateKeyValue
Revision as of 13:33, 22 November 2023 by Misaki Vanilla (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

要約

関数: key llUpdateKeyValue( string k, string v, integer checked, string original_value );

スクリプトのエクスペリエンスに関連付けられたキーと値(kおよびv)を更新する非同期トランザクションを開始します。
これを使用して、このコマンドが成功したか失敗したか、および結果を判断するための対応するdataserverイベントを識別できます。を key で返します。

• string k The key for the key-value pair
• string v The value for the key-value pair. Maximum 2047 characters, or 4095 if using Mono.
• integer checked TRUEの場合、更新はoriginal_valueがキーと値ストア内の値と一致する場合のみ行われます。
• string original_value キーと値ストア内の現在の値と比較する値。

checkedTRUEに設定されている場合、更新はoriginal_valueがキーと値ストア内の現在の値と一致する場合のみ行われ、それ以外の場合はdataserver/jaXP_ERROR_RETRY_UPDATEエラーとともに失敗します。これを使用して、"Wikipedia logo"Atomicityを達成するための使用中フラグを作成できます。

2016年1月1日時点で、キーおよび値の最大バイト数は、LSOおよびMonoスクリプトの両方に対して、キーについて1011、値について4095です。
llUpdateKeyValueを使用して存在しないキーを更新すると、XP_ERROR_KEY_NOT_FOUNDは生成されません。代わりに、指定した値で新しいキーが生成されます。これは、llCreateKeyValueを使用したかのようです。

仕様

Dataserver

dataserverコールバックのパラメータは次のとおりです:

文字列のコンポーネント
• integer success トランザクションが成功した場合は1、失敗した場合は0を指定するブール値。
• integer error 操作が失敗した理由を説明するXP_ERROR_*フラグ。
• string value The value for the key-value pair. Maximum 2047 characters, or 4095 if using Mono. 注意!この値にはカンマが含まれている可能性があります。

警告

  • 以前に体験に関連付けられていたスクリプトを体験のコンパイル機能を持たないクライアントで再コンパイルすると、スクリプトは関連する体験を失います。
  • llKeysKeyValueがキーをCSV形式で返すため、キーにはカンマを含めないように推奨されています。

サンプル

key trans;
default
{
    state_entry()
    {
        trans = llUpdateKeyValue("FOO", "BLAH", TRUE, "BAR");
    }

    dataserver(key t, string value)
    {
        if (t == trans)
        {
            // our llUpdateKeyValue transaction is done
            list result = llCSV2List(value);
            if (llList2Integer(result, 0) == 1)
            {
                // the key-value pair was successfully updated
                llSay(0, "New key-value pair was successfully updated");
            }
            else
            {
                integer error = llList2Integer(result, 1);
                if(error == XP_ERROR_RETRY_UPDATE)
                    llSay(0, "Key-value update failed, checked value is out of date");
                else
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(error) );
            }  
        }
    }
}

このスクリプトは、更新の競合を回避する方法を示しています(2つのスクリプトが同時にストアを更新する状況)。完全なアトミックな更新を行うには、書き込みを行うすべてのスクリプトが仮想ロック($DB_Lock)に従い、更新をupdate_dbステートでのみ行うようにすれば、すべての書き込みがアトミックになります。

key tid;
list tids;

default {
    state_entry() {
        state lock_db;
    }
}

state lock_db {
    state_entry() {
        tid = llUpdateKeyValue("$DB_Lock", "LOCK", TRUE, "unlock");
    }
    dataserver(key did, string value) {
        if(did == tid) {
            string payload = llDeleteSubString(value, 0, 1);
            if(llGetSubString(value+",", 0, 1) == "1,"){
                llUpdateKeyValue("$DB_LockedBy", llDumpList2String([llGetOwner(),llGetKey(),llGetLinkKey(!!llGetLinkNumber()),llGetRegionName(),llGetPos(),llGetAttached()],":"), FALSE, "");
                state update_db;
            } else {
                integer err = (integer)payload;
                if(err == XP_ERROR_RETRY_UPDATE) {
                    llSay(0, "Database is already locked!");
                } else {
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) );
                }
                state error;
            }
        }
    }
}

state update_db {
    state_entry() {
        tids = [
            llUpdateKeyValue("CatsPermissable", "5", FALSE, ""),
            llUpdateKeyValue("MonkeyMutations", "3", FALSE, ""),
            llUpdateKeyValue("CodFlavorSupport", "NEVER", FALSE, "")
        ];
    }
    dataserver(key did, string value) {
        integer i = llListFindList(tid, [did]);
        if(~i) {
            string payload = llDeleteSubString(value, 0, 1);
            if(llGetSubString(value+",", 0, 1) == "1,"){
                tids = llDeleteSubList(tids, i, i);
                if(tids == []) {
                    state unlock_db;
                }
            } else {
                llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage((integer)payload) );
                state error;
            }
        }
    }
}

state unlock_db {
    state_entry() {
        tid = llUpdateKeyValue("$DB_Lock", "unlock", TRUE, "LOCK");
    }
    dataserver(key did, string value) {
        if(did == tid) {
            string payload = llDeleteSubString(value, 0, 1);
            if(llGetSubString(value+",", 0, 1) == "1,"){
                state done;
            } else {
                integer err = (integer)payload;
                if(err == XP_ERROR_RETRY_UPDATE) {
                    llSay(0, "Someone has violated the database lock!");
                } else {
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) );
                }
                state error;
            }
        }
    }
}

state done {
    state_entry(){;}
}

state error {
    state_entry(){;}
}

注意点

コンパイル

スクリプトが Experience に関連するようにするには...

  • 体験をサポートしたクライアントでコンパイルされている必要があります
  • "体験を使用" チェックボックスをチェックする
  • 体験キーの一つを選択する
KBcaution.png 重要 すべての TPV にこの機能があるわけではありません。

特記事項

Search JIRA for related Issues

Signature

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