Jump to content

JSON oddity


Quistess Alpha
 Share

You are about to reply to a thread that has been inactive for 465 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

string json = "{\"a\":\"a\", \"b\":\"b\"}";
json = llJsonSetValue(json,["c"],JSON_DELETE);
llOwnerSay(json); // JSON_INVALID.

Attempting to delete a non-existent key in a JSON object deletes the whole JSON object. Expected behavior?

Edited by Quistess Alpha
Link to comment
Share on other sites

41 minutes ago, Quistess Alpha said:
string json = "{\"a\":\"a\", \"b\":\"b\"}";
json = llJsonSetValue(json,["c"],JSON_DELETE);
llOwnerSay(json); // JSON_INVALID.

Attempting to delete a non-existent key in a JSON object deletes the whole JSON object. Expected behavior?

Yes.  I had to code for this.

When deleting, don't return the result to your "actual" JSON variable.

Instead, return the result to a temporary variable - then make sure that the value returned was NOT JSON_INVALID.  Only then, update your "actual" JSON variable.

string json = "{\"a\":\"a\", \"b\":\"b\"}";
string result;
result = llJsonSetValue(json,["c"],JSON_DELETE);
if (result!=JSON_INVALID)
  json = result;
llOwnerSay(json); // This will be the proper JSON if the value you tried to delete was not present.

 

Link to comment
Share on other sites

13 minutes ago, primerib1 said:

Tangential, but ...

I sometimes wonder, why / when would you want to store data in JSON?

Aside from receiving it from an external system (e.g. script invoking a WebAPI or an outside script pushing HTTP into the script)

Structures, KVP's, lists-within-lists, arrays..

I could go on, and on, and on!

Link to comment
Share on other sites

Using JSON for other than interoperability would be quite specialized and I can't figure out a use for it. Yes, you could express more complicated and dynamic structures more easily, but the performance and memory use compared to LSL data are very poor and those are often a limiting factor.

For comparison: populating a list with 1000 random small integers costs 16k memory* and takes 1.5 seconds. Populating a JSON array structure with the same costs around 24k memory* (random integers in JSON will have random size,  not regular size) and takes 28 seconds.

Reading every value on that list takes so little time it doesn't even register on llGetTime on every run, whereas it takes over 20 seconds from a JSON array.

*=garbage collection not counted, all the discarded dupes due to no modify-in-place lists or strings certainly adds weight and the resulting structure should be about 4000 bytes for a list, and anywhere between 6000-14000 for a JSON string containing the array if I got my data type memory usages right. 

Edited by Frionil Fang
Link to comment
Share on other sites

4 minutes ago, Frionil Fang said:

Using JSON for other than interoperability would be quite specialized and I can't figure out a use for it.

I use it for storing variables for "classes" in a JSON interpreter.   And for storing the JSON "code" itself that the interpreter parses.

And structuring messages between scripts (interoperability).

And a whole lot more.

Link to comment
Share on other sites

Just now, Love Zhaoying said:

I use it for storing variables for "classes" in a JSON interpreter.   And for storing the JSON "code" itself that the interpreter parses.

And structuring messages between scripts (interoperability).

And a whole lot more.

Yes, it's nice to have options. I can't say I have need for a JSON interpreter or code, and if my scripts interoperate, it'll be CSV style or a compact encoding chosen for the situation (why use vectors if your coordinates have 10 bits of range so they can be packed into a single integer, etc.).

Rather than JSON I'd want pointers and direct memory access, but my C is showing again.

Link to comment
Share on other sites

At the moment I'm using it to define a menu structure, to make my menuing system easier to maintain.

Sure, other storage methods are more efficient, but are you really going to remember the exact ordering of a CSV list specification when you want to edit the script a year from now?

Quote
string gLSDPrefix = "QM:";
default
{
    state_entry()
    {   llLinksetDataReset();
        string JSON;
        // /Home
        JSON = llJsonSetValue(JSON,
            ["Type"], "Norm");
        JSON = llJsonSetValue(JSON,
            ["Text"], "This is the main menu.");
        JSON = llJsonSetValue(JSON,
            ["Options"], "List Select, Page B, Secret, Add Access, Rem Access, Textbox, Settings");
        llLinksetDataWrite(gLSDPrefix+"/Home",JSON);
        JSON = "";
        // /Page B
        JSON = llJsonSetValue(JSON,
            ["Type"], "Norm");
        JSON = llJsonSetValue(JSON,
            ["Text"], "This is menu page B.");
        JSON = llJsonSetValue(JSON,
            ["Options"], "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p");
        llLinksetDataWrite(gLSDPrefix+"/Page B",JSON);
        JSON = "";
        // /List Select
        JSON = llJsonSetValue(JSON,
            ["Type"], "List Static");
        JSON = llJsonSetValue(JSON,
            ["Text"], "Please select one:");
        JSON = llJsonSetValue(JSON,
            ["Options"], "listOptions");
        llLinksetDataWrite(gLSDPrefix+"/List Select",JSON);
        llLinksetDataWrite(gLSDPrefix+"listOptions","1,2,3,4,5,6,7,8,9,10,11,12,13,14");
        JSON = "";
        // /Secret
        JSON = llJsonSetValue(JSON,
            ["Type"], "Norm");
        JSON = llJsonSetValue(JSON,
            ["Access"], "Whitelist");
        JSON = llJsonSetValue(JSON,
            ["Text"], "This is a secret menu page.\n"+
            "Access is allowed only to those on the whitelist.");
        //JSON = llJsonSetValue(JSON,
        //    ["Options"], "");
        llLinksetDataWrite(gLSDPrefix+"/Secret",JSON);
        JSON = "";
        // /Add Access
        JSON = llJsonSetValue(JSON,
            ["Type"], "List Dynamic");
        JSON = llJsonSetValue(JSON,
            ["Access"], "Owner, Whitelist");
        JSON = llJsonSetValue(JSON,
            ["Text"], "Please select a nearby person to give access to:");
        JSON = llJsonSetValue(JSON,
            ["Options"], "Nearby");
        llLinksetDataWrite(gLSDPrefix+"/Add Access",JSON);
        JSON = "";
        // /Rem Access
        JSON = llJsonSetValue(JSON,
            ["Type"], "List Dynamic");
        JSON = llJsonSetValue(JSON,
            ["Access"], "Owner, Whitelist");
        JSON = llJsonSetValue(JSON,
            ["Text"], "Please select a person to remove access from:");
        JSON = llJsonSetValue(JSON,
            ["Options"], "Whitelist");
        llLinksetDataWrite(gLSDPrefix+"/Rem Access",JSON);
        JSON = "";
        // /Textbox
        JSON = llJsonSetValue(JSON,
            ["Type"], "Textbox");
        JSON = llJsonSetValue(JSON,
            ["Access"], "Owner, Whitelist");
        JSON = llJsonSetValue(JSON,
            ["Text"], "Please type in a value:");
        llLinksetDataWrite(gLSDPrefix+"/Textbox",JSON);
        JSON = "";
        // /Settings
        JSON = llJsonSetValue(JSON,
            ["Type"], "Switchboard");
        JSON = llJsonSetValue(JSON,
            ["Text"], "Toggle options:");
        JSON = llJsonSetValue(JSON,
            ["Access"], "Owner");
        JSON = llJsonSetValue(JSON,
            ["Display"], "[\"[Off]\",\"[On]\"]"); // Note: this parameter is a JSON Array.
        JSON = llJsonSetValue(JSON,
            ["DisplayMod"], "2"); // length of the display list above.
        JSON = llJsonSetValue(JSON,
            ["Options"], "Lights, Camera, Action, X-factor, Corporeality, Six, Seven, Eight, Nine, Ten, Eleven, Twelve, Thirteen");
        llLinksetDataWrite(gLSDPrefix+"/Settings",JSON);
        llLinksetDataWrite(gLSDPrefix+"X-factor","0, [Low], [Medium], [High]");
        JSON="";
        
        llOwnerSay("LSD reset.");
    }
}

a generic testing example before I started butchering it to my actual use-case.

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

11 minutes ago, Frionil Fang said:

Rather than JSON I'd want pointers and direct memory access, but my C is showing again.

I'm simulating that pretty well. 

Anyway, using JSON to communicate between scripts allows you to easily validate each field with 1 llJsonGetValue() command.  A lot less coding than parsing CSV, and less overhead than lists in my experience.

Link to comment
Share on other sites

2 minutes ago, Quistess Alpha said:

Sure, other storage methods are more efficient, but are you really going to remember the exact ordering of a CSV list specification when you want to edit the script a year from now?

Absolutely not, but everyone has their priorities and I'm fine with trying to figure out what the heck I was doing last time on the rare occasion it's needed. Anything I make just doesn't have the complexity to warrant JSON and I work alone so I don't care if no one else can figure it out. I do often have performance and must fit in a single script -limitations instead, though.

 

4 minutes ago, Love Zhaoying said:

I'm simulating that pretty well. 

Nooo I don't want to live in an immutable JSON string, just let me pointer thrash all over memory, why is that so much to ask. 

  • Like 1
Link to comment
Share on other sites

11 minutes ago, Quistess Alpha said:

At the moment I'm using it to define a menu structure, to make my menuing system easier to maintain.

Sure, other storage methods are more efficient, but are you really going to remember the exact ordering of a CSV list specification when you want to edit the script a year from now?

What I've found over time was, I spent soooo much effort coding around lists when JSON would have made things a lot easier for my old scripting efforts.  Menu-ing is definitely an example.

Link to comment
Share on other sites

1 minute ago, Frionil Fang said:
10 minutes ago, Love Zhaoying said:

I'm simulating that pretty well. 

Nooo I don't want to live in an immutable JSON string, just let me pointer thrash all over memory, why is that so much to ask. 

They are completely..mutable!

And, I'm using GUID's for pointers! I couldn't be more inefficient if I had to!

Link to comment
Share on other sites

Just now, Love Zhaoying said:

They are completely..mutable!

And, I'm using GUID's for pointers! I couldn't be more inefficient if I had to!

They absolutely are not, they're still LSL strings. You're creating new copies with every operation, and that's one of my biggest pet peeves in LSL... the only mutable structures are vectors and rotations but 3/4 floats doesn't go far.

  • Like 4
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 465 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...