Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Need help with LibraryMultidimensionalArray in wiki

Hugsy Penguin
Sky Junkie
Join date: 20 Jun 2005
Posts: 851
07-23-2005 19:44
In the wiki there is code for a multi-dimension array:

http://secondlife.com/badgeo/wakka.php?wakka=LibraryMultidimensionalArray&show_comments=1#comments

On line 35, I had to change the call to randomSeperator to randomSeperatorFrom.

I can get the sample code in the wiki to work (the 12x12 random color code).

I can't get a simple storage/retrieval of an integer to work. The following code outputs a blank line. Can someone please tell me how do this? Thanks!

My exact code:

CODE


// Generates a random string of length len
// from the characters passed to it.
string randomSeperatorFrom(string chars, integer len) {
integer numChars = llStringLength(chars);
integer firstIndex = (integer) llFrand(numChars);
string first = llGetSubString(chars, firstIndex, firstIndex);
if (len == 1)
return first;
chars = llDeleteSubString(chars, firstIndex, firstIndex);
--numChars;
// Generate the last character.
integer lastIndex = (integer) llFrand(numChars);
string last = llGetSubString(chars, lastIndex, lastIndex);
if (len == 2)
return first + last;
chars = llDeleteSubString(chars, lastIndex, lastIndex);
--numChars;
// Generate the string between the first and last chars.
string middle;
integer i;
for (i = 2; i < len; ++i) {
integer randIndex = (integer) llFrand(numChars);
middle += llGetSubString(chars, randIndex, randIndex);
}
return first + middle + last;
}

string SEPERATOR_CHARS = "`~!@#$%^&*()-_+[]{}\|'\";/?.>,<";
integer SEPERATOR_LEN = 3;
string dumpList2String(list src) {
// Generate a seperator not present in any of the
// elements in the list.
string chars = (string) src; // Squashes all elements together.
string seperator;
do {
seperator = randomSeperatorFrom(SEPERATOR_CHARS, SEPERATOR_LEN);
} while (llSubStringIndex(chars, seperator) != -1);
return seperator + llDumpList2String(src, seperator);
}

list parseStringKeepNulls(string src) {
// The seperator should be the first SEPERATOR_LEN
// characters in the string.
return llParseStringKeepNulls(llDeleteSubString(src, 0, SEPERATOR_LEN - 1),
[llGetSubString(src, 0, SEPERATOR_LEN - 1)], []);
}

string NULL = "";
list listReplaceList(list dest, list src, integer start, integer ensureLocation) {
if (ensureLocation && llGetListEntryType(dest, start - 1) == TYPE_INVALID) {
// Fill with nulls until we get to the starting position.
integer len = llGetListLength(dest);
for (len = llGetListLength(dest); len < start; ++len) {
dest += NULL;
}
}
return llListReplaceList(dest, src, start, start + llGetListLength(src) - 1);
}

list getElementAt(list array, list index){
if (index == [])
return array;
integer numIndicies = llGetListLength(index);
list src = array;
integer i;
for (i = 0; i < numIndicies - 1; ++i) {
integer listIndex = llList2Integer(index, i);
string element = llList2String(src, listIndex);
if (llGetSubString(element, 0, 0) == "l")
element = llDeleteSubString(element, 0, 0);
src = parseStringKeepNulls(element);
}
string element = llList2String(src, llList2Integer(index, -1));
if (llGetSubString(element, 0, 0) == "l") {
// Caller is retreiving a dimension.
return parseStringKeepNulls(llDeleteSubString(element, 0, 0));
} else {
return [element];
}
}

// To set an element, we need to extract
// each list starting from where exactly the
// new data will be. In a set of russian dolls, this
// would be equivelant to grabbing the littlest one
// first. then gradually adding back on the layers over it.
// I think its easiest to do this recursively.
list setElementAt(list array, list data, list index) {
string element;
if (llGetListLength(data) > 1) {
// Data is a new dimension:
element = "l" + dumpList2String(data);
} else {
// Data is a single element
element = llList2String(data, 0);
}
if (llGetListLength(index) > 1) {
// index is in the form [a,b,c,d]
// here, we grab the list that d is in.
list containerIndex = llDeleteSubList(index, -1, -1);
list dest = getElementAt(array, containerIndex);
integer listIndex = llList2Integer(index, -1); // Grab d
dest = listReplaceList(dest, [element], listIndex, TRUE); // replace the element in d's list.
// Make sure the recursion treats the container like a list, not an element.
if (llGetListLength(dest) == 1)
dest += "";
return setElementAt(array, dest, containerIndex);
} else {
return listReplaceList(array, [element], llList2Integer(index, 0), TRUE);
}
}

default
{
touch_start(integer total_number)
{
list myArray;
setElementAt(myArray, [42], [0, 0]);
llOwnerSay(llList2String(getElementAt(myArray, [0, 0]), 0));
}
}


Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
07-23-2005 21:35
From: Hugsy Penguin
In the wiki there is code for a multi-dimension array:

http://secondlife.com/badgeo/wakka.php?wakka=LibraryMultidimensionalArray&show_comments=1#comments

On line 35, I had to change the call to randomSeperator to randomSeperatorFrom.


Oops! My bad! I posted a correction to the wiki. :o


From: Hugsy Penguin

<snip>
CODE

default
{
touch_start(integer total_number)
{
list myArray;
setElementAt(myArray, [42], [0, 0]);
llOwnerSay(llList2String(getElementAt(myArray, [0, 0]), 0));
}
}


Ah, this is an error often seen when manipulating lists with llDeleteSubList and llListInsertList functions. Function parameters are pass-by-value critters. This means that when you give a variable to a function, the variable is copied before the function code is run. The original variable is left untouched. Pass-by-reference is the opposite of this, and seems to be what your code is expecting. Pass-by-reference allows you to pass the *actual* variable to the function, without copying it first - this leads to a speed boost as well as being able to manipulate the variable directly within the function. LSL uses pass-by-value.:(

In this particular example, you need to change:
setElementAt(myArray, [42], [0, 0]);
to:
myArray = setElementAt(myArray, [42], [0, 0]);

That should fix your problem :D
==Chris
_____________________
October 3rd is the Day Against DRM (Digital Restrictions Management), learn more at http://www.defectivebydesign.org/what_is_drm
Hugsy Penguin
Sky Junkie
Join date: 20 Jun 2005
Posts: 851
07-23-2005 22:44
From: Christopher Omega


In this particular example, you need to change:
setElementAt(myArray, [42], [0, 0]);
to:
myArray = setElementAt(myArray, [42], [0, 0]);

That should fix your problem :D
==Chris


Doh! I completely missed the fact that setElementAt returns a list. :o

Thanks for your help! :)

HP