Jump to content

A method for using KVP storage


Recommended Posts

Posted (edited)

// I use this KVP wrapper in every script now. It's surprisingly fast, even at full clock rate for animation,

// and all variables are available for easy external debugging, by name. Often, I can eliminate using any native SL variables,

// with little to no impact on execution speed.

// It's not type safe and you can mess up, but it implements pointers and an easy, persistent cross-script variable pool

// makes for much simpler code once you get used to it.

// Setting and examining the contents of any and all variables from the command line or other scripts is a godsend.

// F_( ) is write,  F() is read. _F() is a pointer (returns the value of the value), which I didn't define here for simplicity

// add these 8 lines:

float   F(string name)                  { return (float)llLinksetDataRead(name); }
integer I(string name)                  { return (integer)llLinksetDataRead(name); }
string  S(string name)                  { return llLinksetDataRead(name); }
integer B(string name)                  { if(((float)llLinksetDataRead(name)) != 0.0) return TRUE; return FALSE; }
float   F_(string name, float   value)  { llLinksetDataWrite(name,(string)value); return value; }
integer I_(string name, float   value)  { llLinksetDataWrite(name,(string)((integer)value)); return ((integer)value); }
string  S_(string name, string  value)  { llLinksetDataWrite(name,value); return value; }
integer B_(string name, integer value)  { llLinksetDataWrite(name,(string)((integer)value)); return value; }

// now you can do

S_("name","lumpy"); // assigns "lumpy" to a new variable "name"

llOwnerSay(S("name")); // prints lumpy

// and

S_("query", "name");

llOwnerSay(_S("query")); // also prints lumpy

or

F_("pi", 3.14159);

and 

F_("two_pi", F("pi") * 2.0);

// and

llSetText(S("pi")); // prints without having to typecase to (string)

(always remember that everything is really a string, watch your precision)

- Lots more to this. matrix math, mult/add, lists, delete, search. sort, trig, increment/decrement/double/half...

-- That's enough for now.

 

Edited by Lumpy Tapioca
Link to comment
Share on other sites

Why?!?  You're inserting a whole extra function plus a bunch of casting, to save a little typing?

I_() for example, casts an integer to float, back to integer, then to string — presumably in the name of saving having to write (integer) when you're trying to store the truncation of a float, at the cost of pointless double-casting (there's an implicit cast when you pass an integer to a float argument) when you're actually storing an integer.  If you're storing a float into an integer space, I'd personally argue you want to have to explicitly cast it down the manual way, to make it obvious to yourself that you're doing it intentionally.

That said, if saving a little typing (and the quirks you have embedded in your assumptions there) are sufficiently relevant to you, I'd suggest using Firestorm and it's pre-processor, and do all that as #define's instead.  But also, just:

integer B(string name)                  { return (float)llLinksetDataRead(name) != 0.0; }

Edited by Bleuhazenfurfle
Link to comment
Share on other sites

3 minutes ago, Bleuhazenfurfle said:

Why?!?  You're inserting a whole extra function plus a bunch of casting, to save a little typing?

Plus, the String version is exactly equivalent to just calling llLinksetDataRead()...

@Lumpy Tapioca, thanks for your post. My own scripts use as much script memory as possible, so the extra memory needed for each function would be a deal-killer.  (I don't remember for certain, but I think adding extra functions can result in another 512 bytes memory used, depending on different factors.)

Link to comment
Share on other sites

9 minutes ago, Love Zhaoying said:

@Lumpy Tapioca, thanks for your post. My own scripts use as much script memory as possible, so the extra memory needed for each function would be a deal-killer.  (I don't remember for certain, but I think adding extra functions can result in another 512 bytes memory used, depending on different factors.)

The figure that comes to mind is somewhere around 200 bytes, plus information about the arguments, and whatever code the function contains…  The 512 figure (and the "can result in", should probably be "often results in") comes from bytecode being allocated in 512 byte blocks, so however much space it ends up consuming, you round that up to the nearest 512 bytes.  (Though it's been a while since I cared, so don't take that figure as gospel.)

Link to comment
Share on other sites

13 minutes ago, Bleuhazenfurfle said:

The figure that comes to mind is somewhere around 200 bytes, plus information about the arguments, and whatever code the function contains…  The 512 figure (and the "can result in", should probably be "often results in") comes from bytecode being allocated in 512 byte blocks, so however much space it ends up consuming, you round that up to the nearest 512 bytes.  (Though it's been a while since I cared, so don't take that figure as gospel.)

That's right, depending on your code size / # functions you see the memory used jump in blocks of 512, etc.

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...