Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Using llSetPrimitiveParams with a string

Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-29-2007 09:16
If I write the following code

list pp ;
pp = [PRIM_TEXTURE, ALL_SIDES, "base", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633] ;
llSetPrimitiveParams( pp ) ;

it works. If I write

string s ;
s = "PRIM_TEXTURE, ALL_SIDES, \"base\", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633" ;
llSetPrimitiveParams( [ s ] ) ;

it does NOT work. If I write

list pp ;
string s ;
s = "PRIM_TEXTURE, ALL_SIDES, \"base\", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633" ;
pp = llCSV2List(s) ;
llSetPrimitiveParams( pp ) ;

it does not work too! How can I use llSetPrimitiveParams when I have my primitive parameters in a string?
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
10-29-2007 09:22
From: Eadoin Welles
If I write the following code

list pp ;
pp = [PRIM_TEXTURE, ALL_SIDES, "base", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633] ;
llSetPrimitiveParams( pp ) ;

it works. If I write

string s ;
s = "PRIM_TEXTURE, ALL_SIDES, \"base\", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633" ;
llSetPrimitiveParams( [ s ] ) ;

it does NOT work. If I write

list pp ;
string s ;
s = "PRIM_TEXTURE, ALL_SIDES, \"base\", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633" ;
pp = llCSV2List(s) ;
llSetPrimitiveParams( pp ) ;

it does not work too! How can I use llSetPrimitiveParams when I have my primitive parameters in a string?


That's because things like PRIM_TEXTURE and ALL_SIDES are constants that get replaced by integer values during compilation. If you pass them as a string, the compiler can't do that replacement and the actual words PRIM_TEXTURE and ALL_SIDES will be in the list instead.

In order to get it working, you would need to replace those constants by their actual values at some point, either in the string or by doing a lookup dynamically. You can find out what the values are by doing:

llOwnerSay ((string)PRIM_TEXTURE);

and

llOwnerSay ((string)ALL_SIDES);

The values might be on the wiki too, I haven't checked.

Or you could do:

s = (string)PRIM_TEXTURE + "," + (string)ALL_SIDES + ", \"base\", <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633" ;
_____________________
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-29-2007 11:13
From: Stephen Zenith
That's because things like PRIM_TEXTURE and ALL_SIDES are constants that get replaced by integer values during compilation. If you pass them as a string, the compiler can't do that replacement and the actual words PRIM_TEXTURE and ALL_SIDES will be in the list instead.


So, if I read string from a notecard I have two choices:

parsing the string and substitute keyword by value, that is 'PRIM_TEXTURE' by (string)PRIM_TEXTURE in string, that is '17'

or

using directly the constant value, for example, 17

have I?
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-29-2007 12:42
Mmmm... I tried

string replaceParms(string parms )
{
parms = strReplace(parms, "PRIM_TEXTURE", (string)PRIM_TEXTURE) ;
parms = strReplace(parms, "PRIM_COLOR", (string)PRIM_COLOR) ;
parms = strReplace(parms, "ALL_SIDES", (string)ALL_SIDES) ;
return parms ;
}

Replacement occurs as expected, but still llSetPrimitiveParams(parms) does not work.
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
10-29-2007 15:03
Try dumping the list you get after using llCSV2List with llOwnerSay, and dumping the original list you got by building the list in code, and see what the difference is.
_____________________
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
10-29-2007 16:00
Nevermind :)
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
10-29-2007 16:24
The Wiki has "string to list" and "list to string" functions that (I think) Strife wrote. When going from list to string, these store the data as well as encode the type, and the reverse function creates a list with the correct types. Very useful, but I'm not sure if it'll help you - depends on what you're trying to do. If you can have one script dump the string and then have the other parse it, you can use these 2 functions. If you want to parse something generated by hand, I don't think these functions will help.
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
10-30-2007 08:45
Right.

A list containing a single string is not at all the same thing as a list of values, even if all the values were strings (and for this function, they're not).

So, your attempt wouldn't work even if you replaced the constants like you tried.

You need to get your head around what a list is, and how it differs from a string containing the same text. They're quite different. For example:

list l1 = ["This is a string"];
list l2 = ["This", "is", "a", "string"];

These two variables are very different. llList2String(l1, 0) returns "This is a string", whereas llList2String(l2, 0) returns "This".

The llSetPrimitiveParams() function walks through the list items. It expects the first one to be an integer matching one of the PRIM_XXXX constants. Depending on which one it finds, it expects the next one, two, or more list items to be the parameter values for that constant. When it's done with the arguments, it expects the next list item to be another PRIM_XXXX constant.

As mentioned above, you can build some lists that represent the kinds of things you're trying to do, turn them into strings and chat them and paste them into a notecard, to allow you to configure prim params by notecard. But these stringified lists aren't necessarily going to be very intuitive and readable. If you want intuitive and readable, you have a bit more work to do. If you want something you can fiddle with and don't care about clarity in the notecard, then stringified lists should work just fine.
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-30-2007 15:21
From: Stephen Zenith
Try dumping the list you get after using llCSV2List with llOwnerSay, and dumping the original list you got by building the list in code, and see what the difference is.


Done: no difference.
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-30-2007 15:28
From: Ziggy Puff
The Wiki has "string to list" and "list to string" functions that (I think) Strife wrote. When going from list to string, these store the data as well as encode the type, and the reverse function creates a list with the correct types. Very useful, but I'm not sure if it'll help you - depends on what you're trying to do. If you can have one script dump the string and then have the other parse it, you can use these 2 functions. If you want to parse something generated by hand, I don't think these functions will help.


I am not sure I understand. What I need to do is quite simple in theory.

I have an object O which listens on channel C.
Object O contains a script S and various notecards: N1...Nn
Each notecard contains a list of parameters and values to be used in llSetPrimitiveParams
When I say Nx the script S loads the parameters in Nx notecard, convert them to a list L, and pass L to llSetPrimitiveParms to change the object aspect.

Everything works, but when llSetPrimitiveParms is called, nothing happens, not even an error message. Dumping the list L shows exactly what I expected.
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-30-2007 15:31
From: Lear Cale
Right.

A list containing a single string is not at all the same thing as a list of values, even if all the values were strings (and for this function, they're not).

So, your attempt wouldn't work even if you replaced the constants like you tried.

You need to get your head around what a list is, and how it differs from a string containing the same text. They're quite different. For example:

list l1 = ["This is a string"];
list l2 = ["This", "is", "a", "string"];

...


But I used llCSV2List(s) to create the list from the string.

string any = "This, is, a, string" ;
list some = llCSV2List(any) ;
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
10-30-2007 16:11
llCSV2List will cast all of the list items as type string (which llSetPrimitiveParams isn't going to like), so, I think the sort of thing you need to do is really, really, ugly...

list pp;
string s;

s = "PRIM_TEXTURE, ALL_SIDES, base, <20.0,20.0,0.0>, <0.0,0.0,0.0>, -1.57079633";

pp = llCSV2List(s);

llSetPrimitiveParams([
(string)llList2String(pp,0),
(integer)llList2String(pp,1),
(string)llList2String(pp,2),
(vector)llList2String(pp,3),
(vector)llList2String(pp,4),
(float)llList2String(pp,5)]);

...this is off the top of my head (and I'm not sure what ALL_SIDES will come out like!) but I think this is the kind of thing you face.

In any event you have to get the correct data types with each of the list items going into llSetPrimitiveParams.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
10-30-2007 16:15
I think your problem is the difference between:

integer i = 0;
string s = "0";

list containsIntegers = ;
list containsStrings = ;

If you print them out, both will say 0, but one of them has the number 0, the other has the string "0". The two are different things. When you read in a notecard, you're reading in strings, because there's nothing in the notecard that tells you what the type of a data element is. So even if it says 1.234, it's the string "1.234", not the number 1.234. And so on, for all the types.

Look into Strife's functions in the Wiki, like I suggested. You'll have to use the List2String functions to generate your notecards, and you won't be able to read them yourself, but if you then use the String2List function when you read the notecard, you'll get a list with the correct values, which also have the correct types. Right now you're getting a list with the correct values, but every value is a string, not the type it needs to be.
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-31-2007 01:15
From: Pale Spectre
llCSV2List will cast all of the list items as type string (which llSetPrimitiveParams isn't going to like), so, I think the sort of thing you need to do is really, really, ugly...


It is not only ugly, it is impossible. I do not know a priori the type of each parameter, since I do not know a priori what the notecard contains. It can be any combination of the rtypical parameters passed to llSetPrimitiveParams. It depends on what I wish to change (color, shape, texture, ...)

This is REALLY a problem.
Eadoin Welles
Registered User
Join date: 5 Jan 2007
Posts: 149
10-31-2007 01:17
From: Ziggy Puff

...
Look into Strife's functions in the Wiki, like I suggested. You'll have to use the List2String functions to generate your notecards,
...


Generate notecards? I did not know it was possible to write in notecards! I really miss in SL a good robust database! Sigh...

From: Ziggy Puff

...
and you won't be able to read them yourself, but if you then use the String2List function when you read the notecard, you'll get a list with the correct values, which also have the correct types. Right now you're getting a list with the correct values, but every value is a string, not the type it needs to be.


I manually write my notecards... it looks like I have to replicate the llSetPrimitiveParams parser!!!!! I really hate the fact that LSL does not provide any DB function.
nand Nerd
Flexi Fanatic
Join date: 4 Oct 2005
Posts: 427
10-31-2007 01:33
From: Eadoin Welles
Generate notecards? I did not know it was possible to write in notecards! I really miss in SL a good robust database! Sigh...


The OP was referring to using the function to create the text to be entered into a notecard. Creating the notecard would still be manual.

From: someone
I manually write my notecards... it looks like I have to replicate the llSetPrimitiveParams parser!!!!!


What about having your notecard in the form:
[int] PRIM_SIZE, [vec]<0.5,0.5,1.0>, ... [float]3.5, [string]"BlahBlah"

Then adapt the parser to read in the [int], [vec], [float], [string] etc and do it's job. It wouldn't be elegant but it's an option. If you wish to use the parser as-is, just read in the notecard and replace [int] with "1," [float] with "2," etc (well, you'd need to check the real integers used to define each type).
_____________________
www.nandnerd.info
http://ordinalmalaprop.com/forum - Ordinal Malaprop's Scripting Forum
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
10-31-2007 05:40
OK, I missed the last example in your post above. Ziggy has hit the nail on the head.

What ziggy means is you'll need to write a script to generate the TEXT you'll put in the notecards. The results of Strife's list2String function may not be very intuitively meaningful, as I mentioned above.

Other than including code that knows the data type for each PRIM_XXX code, it's the only way. Such code isn't impossible, or even that unmanageable. There's a limited number of parameter constants. You have to choose the lesser of two evils: hard to edit the notecards, or hard to write the program.
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
10-31-2007 06:07
From: Eadoin Welles
I do not know a priori the type of each parameter, since I do not know a priori what the notecard contains. It can be any combination of the rtypical parameters passed to llSetPrimitiveParams. It depends on what I wish to change (color, shape, texture, ...)
Well, llSetPrimitiveParams only accepts a finite number of parameter types (PRIM_COLOR, PRIM_TYPE, etc.), and each of these must be followed by a specific number of list elements of specific datatypes in order to be valid. So, you could write what amounts to an LSL version of the VM param parser. i.e., If the param type is PARAM_COLOR, it must be followed by three more elements, an integer (face), a vector (color), and a float (alpha).

Yeah, it's ugly, and it'll probably eat up a good chunk of your 16k.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
10-31-2007 08:39
does
llOwnerSay( (string)((integer)"PRIM_SIZE";) );
return
"7"
?

if so you only need
llSetPrimitiveParams( llList2Integer( ourCSVlist, 0 ), etc

if not it will require
list constantNames =[list of string constant names];
list constantValues =[list of their equivalent numbers];

then test each element of the CSV list with
CODE

integer needsReplaced = llListFindList( constantNames, (list)llList2string( ourCSVlist, element ) );
if (~needsReplaced){
ourCSVlist = llListReplaceList( ourCSVlist, llList2Integer( constantValues, needsReplaced ), element, element );
}

can be done in strides, but it's visually simpler this way
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
10-31-2007 09:56
From: Void Singer
does
llOwnerSay( (string)((integer)"PRIM_SIZE";) );
return
"7"
?
Nope. Casting a non-numeric string to integer (or float, for that matter) results in a value of 0. A string containing a constant name can't be cast to it's integral equivalent, since those are only aliases used by the compiler. They're meaningless at run-time.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
10-31-2007 11:11
Right, nand and Learjeff understood what I was saying. I was talking about using a script to generate the strings that go into the notecard. You have to paste it in by hand, you're right, you can't create a notecard straight from a script.

As the others have explained, you need to create a string that include type information, and then parse that string to build a list with the correct types. What I've been trying to say all along is this: Strife has already written a script that does exactly that, and the information is in the Wiki. There are 2 functions - the List2String generates the "coded" string that includes the type information, and the String2List reads that coded string and re-build the original list with the correct types. If I were you, I would just use those 2 functions, instead of writing and debugging a new parser that does the same thing.