User:Decimus Schomer/Scripts/Libraries/LSL sets
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