User:Decimus Schomer/Scripts/Libraries/LSL MDAs

From The SchomEmunity Wiki
Jump to: navigation, search

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.