Aztec Inglewood
Registered User
Join date: 22 Jun 2008
Posts: 3
|
11-16-2009 01:19
Could somebody tell me if they know an lsl equivalent to an evaluate function available in some languages and scripts. ie: To convert a string into an expression and then evaluate it. eg; llevaluate("integer a=5"  ; I need to do this becuase i am reading lots of data from a notecard and i need to be able to set some of the scripts variables from there without specifically testing each one individually with a conditional statement in the script. Thanks for any suggestions.
|
Indeterminate Schism
Registered User
Join date: 24 May 2008
Posts: 236
|
11-16-2009 02:28
Nope, can't be done easily or efficiently, but you can cheat - store your variables in a list: integer Index; list IntNames = []; list IntValues = []; integer GetInt(string IntName) { Index = llListFindList(IntNames, [IntName]); if (Index != -1) return llList2Integer(IntValues, Index); else return 0; // NB: Up to you how you want to signal 'not found' } SetInt(string IntName, integer Value) { Index = llListFindList(IntNames, [IntName]); if (Index != -1) IntValues = llListReplaceList(IntValues, [Value], Index, Index); else llOwnerSay(Not found error - integer '" + IntName + "'"  ; // Same again } You'd need to use llParseString2List() on your notecard line and then call SetInt() with the parsed-out variable name and value. It'll be horribly slow and take extra memory because LSL's list-handling is awful, but at least it will work
|
Aztec Inglewood
Registered User
Join date: 22 Jun 2008
Posts: 3
|
Storing in lists
11-16-2009 03:36
Thanks for the suggestion. It's a clever idea I definately hadn't thought of but I've got so many variables and am allready using lots of lists that this will probably make the whole script too complicated. On the other hand, I suppose I could set just those variables I want set from the notecard this way and leave my other variables as normal. I will need to think about this but thanks for going to the trouble for replying. It has certainly given me some ideas that will be useful.
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
11-16-2009 04:00
You can do your own lookup, too. It looks inefficient but for cases where you're fetching the variable more places than you're storing it you're actually going to be ahead of the game: save_data(string name, string value) { if(name == "variable1"  variable1 = value; else if(name == "variable2"  variable2 = value; // ... }
|
Julie Endsleigh
Registered User
Join date: 18 Jun 2009
Posts: 5
|
11-16-2009 05:52
As this relates to something I've just been looking at, I offer this probably dodgy code. The main script reads a list of names and their values from a notecard, rereading the notecard when it changes. It sends a value to any script that requests one by name, and it broadcasts the values when the notecard changes. The example script requests the values "width", "breadth" and "depth" from the example notecard and scales the prim it is in accordingly. It also responds to the broadcast changes, so it is possible to change the size of the prim just by editing the notecard it contains. Your comments will be appreciated. Main script //notecard to monitor string notecard_name = "New Note";
//link message identifiers integer GET_VALUE = 101; integer VALUE = 102; integer NEW_VALUE = 103; integer NAME_NOT_RECOGNIZED = 104;
//program variables list names = []; list values = []; key notecard_key; key line_query; integer line_number;
GetNotecardData () { //check if the notecard exists and read it if it does if (llGetInventoryType (notecard_name) == INVENTORY_NONE) llOwnerSay ("Notecard \"" + notecard_name + "\" not found."); else { notecard_key = llGetInventoryKey (notecard_name); line_number = 0; line_query = llGetNotecardLine (notecard_name, line_number); } }
default { state_entry() { GetNotecardData (); } dataserver (key query, string data) { if (query == line_query) { if (data == EOF) { //finished reading notecard llOwnerSay ("Notecard \"" + notecard_name + "\" loaded."); } else { //ignore blank, empty and commented lines if (llStringTrim (data, STRING_TRIM) != "" && llGetSubString (data, 0, 1) != "//") { //seperate the note card line into the two elements either side of the "=" sign list elements = llParseString2List (data, ["="], []); //tidy up the name element elements = llListReplaceList (elements, [llToLower (llStringTrim (llList2String (elements, 0), STRING_TRIM))],0, 0); //find the name in the list of names integer index = llListFindList (names, llList2List (elements, 0, 0)); //if not found, add it if (index < 0) { //add the name to the list of names names += llList2String (elements, 0); //add a dummy value to the list of values values += ""; //point index at the new item at the end of the list index = llGetListLength (names) - 1; } //replace the value in the list of values with the data from the notecard values = llListReplaceList (values, llList2List (elements, 1, 1), index, index); //tell everyone that might be interested all about it llMessageLinked (LINK_SET, NEW_VALUE, llList2String (names, index) + "|" + llList2String (values, index), NULL_KEY); } //get the next notecard line line_query = llGetNotecardLine (notecard_name, ++line_number); } } } changed (integer change) { if (change & CHANGED_INVENTORY) { //if the notecard key has changed re-read the notecard if (notecard_key != llGetInventoryKey (notecard_name)) GetNotecardData (); } } link_message (integer sender, integer number, string message, key id) { if (number == GET_VALUE) { //another script requesting a named value integer index = llListFindList (names, [message]); if (index > -1) llMessageLinked (sender, VALUE, llList2String (values, index), id); else llMessageLinked (sender, NAME_NOT_RECOGNIZED, message, id); } } } Example script integer GET_VALUE = 101; integer VALUE = 102; integer NEW_VALUE = 103; integer NAME_NOT_RECOGNIZED = 104;
vector scale = <0.5, 0.5, 0.5>;
key width_id; key breadth_id; key depth_id;
key GenerateKey (string name) { return (key) llInsertString (llInsertString (llInsertString (llInsertString (llMD5String (llGetScriptName () + name, 0), 8, "-"), 13, "-"), 18, "-"), 23, "-"); }
default { state_entry () { width_id = GenerateKey ("width"); breadth_id = GenerateKey ("breadth"); depth_id = GenerateKey ("depth"); llMessageLinked (LINK_SET, GET_VALUE, "width", width_id); llMessageLinked (LINK_SET, GET_VALUE, "breadth", breadth_id); llMessageLinked (LINK_SET, GET_VALUE, "depth", depth_id); } link_message (integer sender, integer number, string message, key id) { if (number == VALUE) { if (id == width_id) scale.x = (float) message; else if (id == breadth_id) scale.y = (float) message; else if (id == depth_id) scale.z = (float) message; } else if (number == NEW_VALUE) { list elements = llParseString2List (message, ["|"], []); string name = llList2String (elements, 0); float value = llList2Float (elements, 1); if (name == "width") scale.x = value; else if (name == "breadth") scale.y = value; else if (name == "depth") scale.z = value; } llSetScale (scale); } } Example notecard width = 1 breadth =2 depth = 4
|
Aztec Inglewood
Registered User
Join date: 22 Jun 2008
Posts: 3
|
own lookup
11-16-2009 07:36
Thanks for this suggestion too. I am allready doing something similar to this but am trying to avoid it..1. because I have so many variables but more also because.. 2. when i develop the script I wont know until after it's developed what the new variables willbe that need to be set this way. I like the way it's done neatly in a function though. It's given me some ideas to tidy up my code.
|