User:Decimus Schomer/Scripts/Libraries/LSL sets
From The Schommunity Wiki
Decimus' user page | Decimus' talk page | Decimus' scripts | Decimus' script libraries | Decimus' projects
Main script library page | LSL MDAs | LSL Sets
Script
// LSL set 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)
////////////////////////////////////////////////////////////////////////////////
// Multi-dimensional array library (required for multi-dimensional sets)
list mda_val_lens;
list mda_val;
integer mda_len(integer idx)
{
if (idx == -1)
return llGetListLength(mda_val_lens);
return llList2Integer(mda_val_lens, idx);
}
////////////////////////////////////////////////////////////////////////////////
// Set library
list set_add(list set, list val)
{
if(val != [0]) // Only want single entry lists. (Comparing lists compares list length; comparison is faster than length checking)
{
llSay(DEBUG_CHANNEL,"set_add: Adding too many sets at once!");
return set;
}
if(!~llListFindList(set,val))
{
set = (set=[])+set+val;
}
return set;
}
set_add_list(list val)
{
integer lenv = llGetListLength(val);
string csvv = llList2CSV(val);
integer x;
integer y;
list l;
integer s = 0;
integer d;
integer mlen = mda_len(-1);
for (y = 0; y < mlen; ++y)
{
d = llList2Integer(mda_val_lens, y);
if (d == lenv)
{
l = llList2List(mda_val, s, s+d);
for (x = 0; x < d; ++x)
{
// It's safe to compare anything as a string, excluding floats that you want accurate to more than six significant figures.
// You can't really compare those anyway.
if (llList2CSV(l) == csvv)
{
return;
}
}
}
s += d;
}
mda_val += val;
mda_val_lens += [lenv];
}
list list_to_set(list l)
{
list copy = [];
integer i;
integer len = llGetListLength(l);
for (i = 0; i < len; ++i)
{
if(llGetListEntryType(l, i) == TYPE_INTEGER)
{
copy = set_add_int(copy, llList2Integer(l, i));
}
else if(llGetListEntryType(l, i) == TYPE_STRING)
{
copy = set_add_str(copy, llList2String(l, i));
}
}
return copy;
}
mda_to_set()
{
integer len = mda_len(-1);
list orig_lens = mda_val_lens;
list orig = mda_val;
mda_val_lens = [];
mda_val = [];
integer i;
integer s;
integer d;
list l;
for (i = 0; i < len; ++i)
{
d = llList2Integer(orig_lens, i);
l = llList2List(orig, s, s+d);
set_add_list(l);
s += d;
}
}
// Compatability functions
set_add_int_list(list val)
{
set_add_list(val);
}
set_add_str_list(list val)
{
set_add_list(val);
}
list int_list_to_set(list l)
{
return list_to_set(l);
}
list str_list_to_set(list l)
{
return list_to_set(l);
}
str_mda_to_set()
{
mda_to_set();
}
int_mda_to_set()
{
mda_to_set();
}
list set_add_int(list set, integer val)
{
return set_add(set,[val]);
}
list set_add_str(list set, string val)
{
return set_add(set,[val]);
}
Usage
Put this script at the start of any script requiring sets. Then, make a normal list (sets are just lists but with specific functions used to update them) and, to append an item, instead of putting l += [1], put set_add_int(l, 1) or the equivalent for whatever other type you're using (and, to convert a list to a set, put int_list_to_set(l) or the equivalent for a different type)
To use multi-dimensional sets, you need to use mda_val and mda_val_lens in the same way as you would for the functions in the MDA library.
Note: I've moved the comments to the Talk page, so please put any other comments on there