08/11/22[]
以前書いた並べ替えスクリプトを最適化しようということで、EhterPadを使ってリアルタイムにコラボしながらスクリプトを書き換えてみました。
9/27のコードの「要素数を3の倍数にあわせる」部分に無駄があったのと、要素の並べ替え処理は結局3個単位で行った方が早いことなどから、最終的に以下のようなコードになりました。
list pads = [ " ", " " ];
list DialogButtonSort( list src ) {
// 要素数を3の倍数にあわせる
integer pad = ( 9999999 - llGetListLength( src ) ) % 3;
if ( pad-- ) { src += llList2List( pads, 0, pad ); }
// 末尾から3つずつ抽出する
return llList2List( src, 9, 11 ) + llList2List( src, 6, 8 ) +
llList2List( src, 3, 5 ) + llList2List( src, 0, 2 );
}
要素数を3の倍数に合わせる部分は、リストの要素数は現実問題として9999999よりも小さいだろうという前提条件で成り立つコードになっています。integerの範囲であれば、もう少し大きな数字にしておいても内部的には全く同じです。
また、実際に不足分の要素を追加する処理では、不足している要素数が1か2の時にだけ要素の追加処理を行っています。
08/09/27[]
LSLからダイアログを表示する場合、表示するボタンをリスト変数で指定しますが、ダイアログにはリストで指定したボタンが左下から右上に向かって並べられます。 これは直感的ではないため、左上から右下へ向かって並ぶようにあらかじめボタンのリストを並べ替えれば分かりやすくなります。
1つ目に、オーソドックスにリストの要素を1つずつ並べ替える方法です。
list dialogButtonSort1( list src ) {
// 要素数を3の倍数にあわせる
integer max = llGetListLength( src );
integer pad = ( -1 * max % 3 + 3 ) % 3;
max += pad;
while ( --pad >= 0 ) {
src += " ";
}
// 1つずつ並べ替える。
integer i;
integer target_index;
list ret;
for ( i = 0; i < max; ++i ) {
target_index = max - 3 * ( 1 + i / 3 ) + i % 3;
ret += llList2String( src, target_index );
}
return ret;
}
初めにリストの要素数が3の倍数になるように調整した後、元のリストの要素を意図した順に並ぶように1つずつ抽出して戻り値用のリストに追加しています。
ただ、要素は必ず3つずつのグループで並べ替えるので、llList2Listを使用して以下のようにまとめて処理すると、ループ回数を減らせます。
list dialogButtonSort2( list src ) {
// 要素数を3の倍数にあわせる
integer max = llGetListLength( src );
integer pad = ( -1 * max % 3 + 3 ) % 3;
max += pad;
while ( --pad >= 0 ) {
src += " ";
}
// 末尾から3つずつ抽出する
list ret;
while ( max > 0 ) {
ret += llList2List( src, max - 3, max - 1 );
max -= 3;
}
return ret;
}
※llList2Listは、元のリストから複数の要素をリストとして抽出できます。
ところで、llList2Listはパラメータで指定するインデックスがリストの範囲外であってもエラーとはならず、うまく処理してくれるという仕様を利用すると、上のコードのように真面目にインデックスを計算する必要がなくなります。
例えばllDialogのページにあるサンプルコードでは、単純にllList2Listを固定インデックスで4回呼び出すことで、ほぼ同様の並べ替え処理を行っています。
要素が少ない場合でもllList2Listを4回呼び出すため、関数呼び出しのコストが無駄になりますが、インデックス計算を行っていない点やコードがシンプルになる点で、こちらの方法を好む方もいるかもしれません。
※今のところ要素が高々12個ですし、頻繁に呼び出される処理でもないため、
※処理コストの差よりもコードのシンプルさなどを重視してもよいかもしれません。
このページのTinyURL:http://tinyurl.com/SC-DialogButton