Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: RLib - A Developer Library

Hitani Fugazi
Registered User
Join date: 14 Jun 2006
Posts: 7
06-21-2006 14:59
NOTE: As used here, 'Developer Library' is a collection of general purpose functions commonly used by developers

RLib 2.0 - A LSL Developer Library
Created by Hitani Fugazi


RLib is designed to make your lives easier, by allowing you to write in LSL logically, without having to stress over unimportant, yet essential details. Simply copy the RLib source to the top of any script you wish to use it in, and you will be able to use all of these functions with ease. RLib has been written carefully, taking every possible precaution to make sure that it is functional, flexible, and will not clutter your code.

Questions, comments, and concerns to:
[email]instinkt.aka.ink@gmail.com[/email]


Function List

string rl_GetFirstName ( key id )
Retrieves the first name of an avatar

Parameters:
  1. id - key of the avatar

Returns:
  1. The first name of the avatar specified, as a string




string rl_GetLastName ( key id )
Retrievs the last name of an avatar

Parameters:
  1. id - key of the avatar

Returns:
  1. The last name of the avatar specified, as a string




string rl_Replace ( string str, string pattern, string alternative )
Replaces a pattern in a string with an alternative pattern

Parameters:
  1. str - The string
  2. pattern - The pattern to find
  3. alternative - The string to replace pattern with

Returns:
  1. The string with pattern replaced by alternative

Example:
  1. rl_Replace( "the bar", "the", "foo" ) = "foo bar"
  2. rl_Replace( "Welcome, come right in!", "come", "fly" ) = "Welfly, fly right in!"




integer rl_RandomInteger ( integer min, integer max )
Retrieves a random integer between min and max, inclusively

Parameters:
  1. min - The minimum value of the integer
  2. max - The maximum value of the integer

Returns:
  1. A random integer from min to max




list rl_Int2Bin ( integer num )
Converts a signed 32-bit integer into a list of integers representing each bit

Parameters:
  1. num - An integer to convert

Returns:
  1. A list of 'bits' ( integers with a value of 1 or 0 )

Example:
  1. rl_Int2Bin( 32 ) = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
  2. rl_Int2Bin( 21474836487 ) = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Notes:
  1. Signed integers are not supported by LSL. Becuase of this, num has a maximum value of 21474836487
  2. Although the maximum value uses only 31 bits, to prevent incompatibility with future updates, the list returned by this function will always have a length of 32
  3. An integer with a value of 0 is FALSE
  4. An integer with a value of 1 is TRUE
  5. 'if ( a == TRUE )' is the same as 'if ( a )'




integer rl_Bin2Int ( list bin )
Converts a list of bits into a signed integer

Parameters:
  1. bin - A list of bits, either TRUE ( 1 ) or FALSE ( 0 )

Returns:
  1. An integer represented by the bits provided

Example:
  1. rl_Bin2Int( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] ) = 32
  2. rl_Bin2Int( [1, 0, 0, 0, 0, 0] ) = 32

Notes:
  1. The list bin does not have to have a length of 32, any extra FALSE values proceeding the first occurrence of 1 in the list may be omitted
  2. The list bin cannot have a length higher than 31
  3. Regardless of the length of the length of bin, 'llList2Key( bin, llGetListLength( bin ) - 1 )' should represent 'llPow( 2, 0 )', or 2 to the 0 power




string rl_Trim ( string str )
Removes leading and trailing spaces from a string

Parameters:
  1. str - The string to trim

Returns:
  1. A string with no leading or trailing spaces


Source:
Place this at the top of any script to use it there
CODE
string rl_GetFirstName ( key id )
{
return llGetSubString( llKey2Name( id ), 0, llSubStringIndex( id, " " ) - 1 );
}

string rl_GetLastName ( key id )
{
return llGetSubString( llKey2Name( id ), llSubStringIndex( id, " " ) + 1, - 1 );
}

// Submitted by Christopher Omega
string rl_Replace ( string str, string pattern, string alternative )
{
return llDumpList2String( llParseStringKeepNulls( str, [pattern], [] ), alternative );
}

integer rl_RandomInteger ( integer min, integer max )
{
return llFloor( llFrand( max - min + 1 ) ) + min;
}

// Submitted by Strife Onizuka
list rl_Int2Bin ( integer num )
{
integer i = 32;
list binary = [];
do
{
binary += !!( num & ( 1 << --i ) );
} while ( i );
return binary;
}

// Submitted by Strife Onizuka
integer rl_Bin2Int ( list bin )
{
integer val = 0;
integer i = llGetListLength( bin );
while( i )
{
if(llList2Integer( bin, -( i-- ) ) ) //allows for the use of hex strings
{
val = val | ( 1 << i );
}
}
return val;
}

// Submitted by Sol Columbia
string rl_Trim ( string str )
{
if ( llGetSubString( str, 0, 0 ) == " " )
{
str = rl_Trim( llDeleteSubString( str, 0, 0 ) );
}
if ( llGetSubString( str, -1, -1 ) == " " )
{
str = rl_Trim( llDeleteSubString( str, -2, -1 ) );
}
return str;
}


Credits:
  1. Hitani Fugazi
  2. Christopher Omega
  3. Strife Onizuka
  4. Sol Columbia
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Original Thread
06-21-2006 15:32
/15/c7/115315/1.html
_____________________
i've got nothing. ;)
Hitani Fugazi
Registered User
Join date: 14 Jun 2006
Posts: 7
Original Thread
06-21-2006 16:04
That link doesn't work...
/15/e7/115536/1.html

Also, may I ask why you added this thread here?
Anti Antonelli
Deranged Toymaker
Join date: 25 Apr 2006
Posts: 1,091
06-21-2006 18:38
From: Hitani Fugazi
That link doesn't work...
/15/e7/115536/1.html

Also, may I ask why you added this thread here?
Every thread in the Scripting Library has a corresponding thread here in Scripting Tips for the purpose of discussion, presumably to keep the Library threads free of clutter. My understanding is that as moderator Nada also approves threads for inclusion in the Library, and I imagine it is during that process that he makes these mirror threads with links back and forth.

I'm only butting in because all this leads me to believe that Nada is probably a fairly busy guy. ;)
Hitani Fugazi
Registered User
Join date: 14 Jun 2006
Posts: 7
06-21-2006 18:53
Oh, ok. Sorry, I'm kinda new here. What do you think of the code, though?
Rhysling Greenacre
Registered User
Join date: 15 Nov 2003
Posts: 132
06-21-2006 21:21
Good functions. Thanks!
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
06-21-2006 21:43
Very nice! These come in handy in quite a good number of scenarios.
A few suggestions:
Perhaps it would be more efficiant to use a string instead of a list in your binary conversion functions. A "1" or "0" only uses one byte in memory, whereas the integer uses 4, along with the list gook that maintains its element type.

For string replacement, there's a neat little trick that uses the list parsing functions:

CODE

string rl_Replace ( string str, string pattern, string alternative )
{
return llDumpList2String(llParseString2List(str, [pattern], []), alternative);
}


And another with casting:
CODE

string rl_Implode ( list peices, string glue )
{
if (glue == "")
{
return (string)peices;
}
else
{
return llDumpList2String(peices, glue);
}
}

==Chris
Yumi Murakami
DoIt!AttachTheEarOfACat!
Join date: 27 Sep 2005
Posts: 6,860
06-22-2006 04:02
RL_Explode is just the same as llParseString2List isn't it?

Otherwise, some very nice ideas there!
Hitani Fugazi
Registered User
Join date: 14 Jun 2006
Posts: 7
06-22-2006 05:37
Yes, those were just there in case people didn't know about them. As far as using a string, you would end up making it into a list anyway to work with the values.
Lee Dimsum
Registered User
Join date: 22 Feb 2006
Posts: 118
06-22-2006 09:35
My two L$:
A mod pow function which is alot faster than LL's one:

integer rl_ModPow(integer a, integer b, integer c)
Returns (a^b) % c

Parameters:
  1. b - key of the avatar

Returns:
  1. Returns a raised to the b power, mod c.




CODE

integer rl_ModPow( integer a, integer b, integer c )
{
integer result = 1;
while( b > 0 )
{
if ((b & 1) > 0) result = (result * a) % c;
b = b >> 1;
a = (a * a) % c;
}
return result;
}
Sol Columbia
Ding! Level up
Join date: 24 Sep 2005
Posts: 91
06-22-2006 16:10
My little trim function - removes any leading and trailing spaces from string s and returns the modified string.

CODE

string trim (string s) {
if (llGetSubString(s, 0, 0) == " ") s = trim(llDeleteSubString(s, 0, 0));
if (llGetSubString(s, -1, -1) == " ") s = trim(llDeleteSubString(s, -2, -1));
return s;
}

usage:
CODE

string stuff = " sfljsldfj slkfslfj ";
stuff = trim(stuff);
llSay(0, stuff);

returns... "sfljsldfj slkfslfj"

Useful for validating data from notecards, voice commands, etc.
_____________________
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
06-22-2006 18:37
Here's how I write these functions; they're much more efficient now.
CODE
string rl_GetFirstName ( key id )
{
return llGetSubString( id = llKey2Name(id), 0, llSubStringIndex( id, " " ) - 1 );
}

string rl_GetLastName ( key id )
{
return llGetSubString( id = llKey2Name(id), llSubStringIndex( id, " " ) + 1, - 1 );
}

//list rl_Explode ( string str, string pattern )
//removed -- llParseString2List is waay faster

//string rl_Implode ( list pieces, string glue )
//removed -- llDumpList2String is better

string rl_Replace ( string str, string pattern, string alternative )
{
return llDumpList2String( llParseStringKeepNulls( str, [ pattern ], [] ), alternative );
}

integer rl_RandomInteger ( integer min, integer max )
{
return (integer)(llFrand( max - min + 1 ) + min );
}

//Didn't bother with Int2Bin or Bin2Int, as I can't see a use for them
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
06-23-2006 12:00
faster versions.
I cannot imagine ever using these functions.

It should be noted, that even if you don't use a function in your LSL script, it will still be included in the bytecode (dead code, wasted memory).

CODE

list rl_Int2Bin ( integer num )
{
integer i = 32;
list binary = [];
do
binary += !!( num & (1 << --i) );
while (i);
return binary;
}

integer rl_Bin2Int ( list bin )
{
integer val = 0;
integer i = llGetListLength( bin );
while(i)
if(llList2Integer( bin, -(i--)))//allows for the use of hex strings
val = val | (1 << i);
return val;
}
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Hitani Fugazi
Registered User
Join date: 14 Jun 2006
Posts: 7
06-23-2006 16:40
I appretiate your support in telling me how to write my code. For those of you who actually contributed, I appretiate it. I am only a few days old, so do not blame me for messing a few things up in my first script. As for rl_Bin2Int and rl_Int2Bin, I used them when working with llMessageLinked with a texture sorter. The texture sorter was a 4x4 grid of 16 panels, and could zoom in or out 3 levels. Level 1 showed 16 textures. Level 2 showed 4 textures, each 2x2 panels. Level 3 showed 1 texture. How am I supposed to cram 4 variables into the 3 that LSL gives me with llMessageLinked? I seperated the bits. By knowing the x and y location of the panels was limited 1-4, I used two bits for each. Also, since the level is limited 1-3, the closest power of 2 that it can fit into is 2, so I used 2 more bits for the level. In the end, I send 3 integers and one string through llMessageLinked, with room to spare.

Edit: I read my post, and I may seem a bit upset. I'm not, I was not sarcastic in the first sentence.
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
06-23-2006 17:27
Hitani, a better way to do that would be to send it as a CSV list, so it's "integer1,integer2,integer3,string", and then use llParseString2List. This removes the overhead of the int2bin and bin2int calls.
Hitani Fugazi
Registered User
Join date: 14 Jun 2006
Posts: 7
06-24-2006 09:28
That's true, but I didn't know about that at the time. What if you were using it for a parameter for llRezObject?
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
06-24-2006 16:00
I didn't relize you were new, welcome to scripting in SL :)
if you have any questions, please ask in this forum or on the wiki.

We didn't mean to imply anything about your code by rewriting it. It's just something we. It's a great opertunity to look into other peoples minds.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
daka Kaos
Registered User
Join date: 30 Aug 2005
Posts: 2
06-27-2006 16:27
From: Hitani Fugazi
That's true, but I didn't know about that at the time. What if you were using it for a parameter for llRezObject?


You know I have often wondered why so many lsl functions (especially llRezObject) use an integer as the datatype to pass as a parameter instead of a string. We trying to keep the stack size down or something? Using a string in CSV form would allow me to pass many parameters.

Thanks for the functions, that was a nice contribution and it spawned a lot of good information from people who commented.

- Daka
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
07-01-2006 11:31
The getFirstName and getLastName functions don't work-- you're trying to find a space character in a key. I would recommend testing things before you post them.

Also, I was the one who wrote that replacement function-- Christopher Omega's one used llParseStringToList, not llParseStringKeepNulls.
Nynthan Folsom
Registered User
Join date: 29 Aug 2006
Posts: 70
12-01-2006 08:46
From: Keknehv Psaltery
Hitani, a better way to do that would be to send it as a CSV list, so it's "integer1,integer2,integer3,string", and then use llParseString2List. This removes the overhead of the int2bin and bin2int calls.


Actually, couldn't you use the bitwise operators to pack/unpack the values into/from a single integer? There are 32 bits in an integer. If you have 4 integer variables, you can encode 4 8-bit values in one single integer.

For example if you have integers a, b, c, d you could encode them in one single integer like this:

integer packed;

packed = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255);

And to unpack

a = packed >> 24;
b = (packed >> 16) & 255;
c = (packed >> 8) & 255;
d = packed & 255;

It would be much faster and less memory intensive than using llParseString2List.
Evo Commons
Registered User
Join date: 17 Apr 2006
Posts: 0
01-06-2007 15:16
Does not seem like the need to remove leading and trailing spaces occurs very often but I thought I would throw this out there as a replacement for the one in the library. Uses less active memory (no nested function calls to unwind) and is also slightly faster then previous example.

CODE

string fncTrimSpaces(string str)
{
while (llGetSubString(str, 0, 0) == " ")
str = llDeleteSubString(str, 0, 0);
while (llGetSubString(str, -1,-1) == " ")
str = llDeleteSubString(str, -1, -1);
return str;
}