User:Decimus Schomer/Scripts/Libraries/LSL MDAs
Decimus' user page | Decimus' talk page | Decimus' scripts | Decimus' script libraries | Decimus' projects
Main script library page | LSL MDAs | LSL Sets
Script
// LSL multi-dimensional array library // Copyright (C) 2007 Decimus Schomer // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // (you can find version 2 of the GPL at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) // NOTE: as of yet, 3+-dimensional arrays are not directly supported, but a workaround can be used to simulate them. list mda_val_lens; list mda_val; string mda_get_string(integer x, integer y) { integer idx = llRound(llListStatistics(LIST_STAT_SUM,llList2List(mda_val_lens,0,y-1))); if (x >= llList2Integer(mda_val_lens, y)) return ""; return llList2String(mda_val, idx+x); } integer mda_get_integer(integer x, integer y) { integer idx = llRound(llListStatistics(LIST_STAT_SUM,llList2List(mda_val_lens,0,y-1))); if (x >= llList2Integer(mda_val_lens, y)) return -1; return llList2Integer(mda_val, idx+x); } integer mda_len(integer idx) { if (idx == -1) return llGetListLength(mda_val_lens); return llList2Integer(mda_val_lens, idx); } mda_append_string(integer y, string val) { integer idx = llRound(llListStatistics(LIST_STAT_SUM,llList2List(mda_val_lens,0,y))); mda_val = llListInsertList(mda_val, [val], idx); mda_val_lens = llListReplaceList(mda_val_lens, [llList2Integer(mda_val_lens, y) + 1], y, y); } mda_append_integer(integer y, integer val) { integer idx = llRound(llListStatistics(LIST_STAT_SUM,llList2List(mda_val_lens,0,y))); mda_val = llListInsertList(mda_val, [val], idx); mda_val_lens = llListReplaceList(mda_val_lens, [llList2Integer(mda_val_lens, y) + 1], y, y); } mda_append_row_str(string s) { mda_val_lens = (mda_val_lens=[])+mda_val_lens+[1]; // More efficient mda_val = (mda_val=[])+mda_val+[s]; } mda_append_row_int(integer i) // The LSL compiler would like to know what an "int" is. { mda_val_lens = (mda_val_lens=[])+mda_val_lens+[1]; // More efficient mda_val = (mda_val=[])+mda_val+[i]; } mda_remove_row(integer y) { integer idx = 0; integer i; for (i = 0; i < y; i++) idx += llList2Integer(mda_val_lens, i); mda_val = llDeleteSubList(mda_val, idx, idx+llList2Integer(mda_val_lens, y)-1); // llListRemoveList doesn't exist. List functions are very inconsistent. mda_val_lens = llDeleteSubList(mda_val_lens, y, y); } mda_remove_item(integer x, integer y) { integer idx = 0; integer l; if (x >= llList2Integer(mda_val_lens, y)) return; l = llList2Integer(mda_val_lens, y); if (l == 1) mda_remove_row(y); idx = llRound(llListStatistics(LIST_STAT_SUM,llList2List(mda_val_lens,0,y-1))); mda_val = llDeleteSubList(mda_val, idx+x, idx+x); // This is pass-by-value, not pass-by-reference. Need to assign the results to something! :p mda_val_lens = llListReplaceList(mda_val_lens, [l - 1], y, y); } list mda_get_row(integer y) { integer idx = llRound(llListStatistics(LIST_STAT_SUM,llList2List(mda_val_lens,0,y-1))); return llList2List(mda_val, idx, idx+llList2Integer(mda_val_lens, y) - 1); // I'm just guessing at what this is meant to return. You didn't specify anything. }
Usage
Put this script at the start of any script requiring two-dimensional arrays. The only thing you need to do is put a copy of the two lists you have into specific variables - the list of values (strings or ints) into mda_val and the list of lengths (ints) into mda_val_lens; the operations all read the values from this (because of a couple of limitations of LSL) and store modified versions of it into them (because you can't modify copies of lists other than the copy you have); after calling mda_append_string and mda_append_row, you *must* copy mda_val and mda_val_lens back into your own storage so it isn't overwritten.