JsonStore Module

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
(key requestID = JsonReadNotecard(key storeID, string path, key assetID))
(Separate functions into basic and advanced in an effort to help readers who don't require the more sophisticated stuff. Changes header levels to compensate for this.)
Line 1: Line 1:
== Introduction ==
+
= Introduction =
  
 
The JsonStore module enables scripts and region modules to share structured data among themselves.  
 
The JsonStore module enables scripts and region modules to share structured data among themselves.  
  
== Enabling the Module ==
+
= Enabling the Module =
  
 
Add the following to your OpenSim.ini to enable the JsonStore module: 
 
Add the following to your OpenSim.ini to enable the JsonStore module: 
Line 17: Line 17:
 
</pre>
 
</pre>
  
== JsonStore Path Syntax ==
+
= JsonStore Path Syntax =
  
 
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with "{" and "}" characters. Array references are quoted with "[" and "]". When there is no ambiguity, the '.' separator can be dropped.   
 
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with "{" and "}" characters. Array references are quoted with "[" and "]". When there is no ambiguity, the '.' separator can be dropped.   
  
=== Formal Syntax ===
+
== Formal Syntax ==
  
 
<pre>
 
<pre>
Line 31: Line 31:
 
</pre>
 
</pre>
  
=== Examples ===
+
== Examples ==
  
 
<pre>
 
<pre>
Line 44: Line 44:
 
</pre>
 
</pre>
  
== JsonStore Value Syntax ==
+
= JsonStore Value Syntax =
  
== JsonStore Script Functions ==
+
= JsonStore Script Functions =
 +
 
 +
== Basic Functions ==
 +
 
 +
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.
  
 
*JsonCreateStore  
 
*JsonCreateStore  
 
*JsonDestroyStore  
 
*JsonDestroyStore  
*JsonReadNotecard
 
*JsonWriteNotecard
 
 
*JsonTestPath/JsonTestPathJson  
 
*JsonTestPath/JsonTestPathJson  
 
*JsonGetValue/JsonGetValueJson  
 
*JsonGetValue/JsonGetValueJson  
*JsonTakeValue/JsonTakeValueJson
 
*JsonReadValue/JsonReadValueJson
 
 
*JsonSetValue/JsonSetValueJson
 
*JsonSetValue/JsonSetValueJson
 +
*JsonReadNotecard
 +
*JsonWriteNotecard
  
=== key storeID = JsonCreateStore(string jsonvalue) ===
+
=== key storeID = JsonCreateStore(string jsonvalue) ===
  
 
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned.  
 
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned.  
Line 175: Line 177:
 
}
 
}
 
</source>
 
</source>
 
=== key requestID = JsonTakeValue(key storeID, string path)<br>key reqeustID = JsonTakeValueJson(key storeID, string path)  ===
 
 
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.
 
 
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.
 
 
<source lang="lsl">
 
default
 
{
 
    state_entry()
 
    {
 
        key requestID = JsonTakeValue(storeID,"Event.Lock");
 
    }
 
 
    link_message(integer sender, integer ival, integer sval, key id)
 
    {
 
        if (sender != -1) return;
 
        if (id == requestID)
 
        {
 
            // we now have a "lock"
 
            llOwnerSay("read: " + sval);
 
 
            // release the "lock" by placing the value back in the store
 
            llSetValue(storeID,"Event.Lock",sval);
 
        }
 
    }
 
}
 
</source>
 
 
=== key requestID = JsonReadValue(key storeID, string path)<br>key reqeustID = JsonReadValueJson(key storeID, string path) ===
 
 
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.
 
 
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.
 
  
 
=== int status = JsonSetValue(key storeID, string path, string value)<br>int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===
 
=== int status = JsonSetValue(key storeID, string path, string value)<br>int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===
Line 251: Line 218:
 
</source>
 
</source>
  
== Examples ==
+
== Advanced Functions ==
 +
 
 +
These are functions that allow scripts to receive notifications of values when they become available. This is useful for signalling between scripts or between scripts and region modules.
 +
 
 +
*JsonTakeValue/JsonTakeValueJson
 +
*JsonReadValue/JsonReadValueJson
 +
 
 +
=== key requestID = JsonTakeValue(key storeID, string path)<br>key reqeustID = JsonTakeValueJson(key storeID, string path)  ===
 +
 
 +
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.
 +
 
 +
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.
 +
 
 +
<source lang="lsl">
 +
default
 +
{
 +
    state_entry()
 +
    {
 +
        key requestID = JsonTakeValue(storeID,"Event.Lock");
 +
    }
 +
 
 +
    link_message(integer sender, integer ival, integer sval, key id)
 +
    {
 +
        if (sender != -1) return;
 +
        if (id == requestID)
 +
        {
 +
            // we now have a "lock"
 +
            llOwnerSay("read: " + sval);
 +
 
 +
            // release the "lock" by placing the value back in the store
 +
            llSetValue(storeID,"Event.Lock",sval);
 +
        }
 +
    }
 +
}
 +
</source>
 +
 
 +
=== key requestID = JsonReadValue(key storeID, string path)<br>key reqeustID = JsonReadValueJson(key storeID, string path) ===
 +
 
 +
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.
 +
 
 +
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.
 +
 
 +
= Examples =
  
 
*[[OSSL Script Library/JsonStore|Generator/Consumer]]
 
*[[OSSL Script Library/JsonStore|Generator/Consumer]]

Revision as of 17:39, 6 February 2013

Contents

Introduction

The JsonStore module enables scripts and region modules to share structured data among themselves.

Enabling the Module

Add the following to your OpenSim.ini to enable the JsonStore module: 

[JsonStore]
Enabled = true

You will also need to enable permission for MOD functions to run, if you have not done so already:

[XEngine]
AllowMODFunctions = true

JsonStore Path Syntax

A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with "{" and "}" characters. Array references are quoted with "[" and "]". When there is no ambiguity, the '.' separator can be dropped.

Formal Syntax

Path --> Token | Path '.' Token
Token --> '[' Index ']' | '{' Identifier '}' | SimpleIdentifier
Index --> '+' | [0-9]+
Identifier --> [^}]+
SimpleIdentifier --> [a-zA-Z]+

Examples

"elem"
"[0]"
"elem[0]"
"elem.[0]"
"{elem}.[0]"
"{foo.bar}.[0]" // this is a two token path with the identifier "foo.bar" and array reference "0"
"{foo}.{bar}.[0]"
"foo.bar[0].goof" // this is a four token path: [{foo}, {bar}, [0], {goof}]

JsonStore Value Syntax

JsonStore Script Functions

Basic Functions

These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.

  • JsonCreateStore
  • JsonDestroyStore
  • JsonTestPath/JsonTestPathJson
  • JsonGetValue/JsonGetValueJson
  • JsonSetValue/JsonSetValueJson
  • JsonReadNotecard
  • JsonWriteNotecard

key storeID = JsonCreateStore(string jsonvalue)

Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned.

// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' 
// and a key 'Event' pointing to an array with two values '1, 2'
default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
    }
}

integer status = JsonDestroyStore(key storeID)

Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful.

default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
        integer res = JsonDestroyStore(storeID);
 
        llOwnerSay("Result " + (string)res);
    }
}

key requestID = JsonWriteNotecard(key storeID, string path, string notecard)

Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.

key requestID;
 
default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
 
        requestID = JsonWriteNotecard(storeID, "/", "nc1");
    }
 
    link_message(integer sender, integer ival, string sval, key id)
    {
        if (sender != -1) return;
        if (id == requestID)
            llOwnerSay("Notecard written");
    }
}

key requestID = JsonReadNotecard(key storeID, string path, key assetID)

Request that the Json encoded content of a notecard be decoded and  placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.

This example presumes that the prim contains the "nc1" notecard saved in the JsonWriteNotecard() example.

key storeID;
key requestID;
 
default
{
    touch_start(integer n)
    {        
        requestID = JsonReadNotecard(storeID, "/", "nc1");
    }
 
    link_message(integer sender, integer ival, string sval, key id)
    {
        if (sender != -1) return;
        if (id == requestID)
            llOwnerSay("notecard read: " + JsonGetValueJson(storeID,"Event[0]"));
    }
}

int status = JsonTestPath(key storeID, string path)
int status = JsonTestPathJson(key storeID, string path)

Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.

default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
        integer res = JsonTestPath(storeID, "Hello");
 
        llOwnerSay("Result " + (string)res);
    }
}

string value = JsonGetValue(key storeID, string path)
string jsonvalue = JsonGetValueJson(key storeID, string path)

Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.

default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
        string res = JsonGetValue(storeID, "Hello");
 
        llOwnerSay("Result " + (string)res);
    }
}

int status = JsonSetValue(key storeID, string path, string value)
int status = JsonSetValue(key storeID, string path, string jsonvalue)

Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.

default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
 
        integer intRes = JsonSetValue(storeID, "Pancake/Banana", "Apple");   
        llOwnerSay("Set result " + (string)intRes);
 
        string stringRes = JsonGetValue(storeID, "Pancake/Banana");
        llOwnerSay("Get result " + stringRes);
    }
}

int status = JsonRemoveValue(key storeID, string path)

Remove from the store the value identified by the path.

default
{
    touch_start(integer n)
    {
        key storeID = JsonCreateStore("{'Hello' : 'World', 'Event' : ['1', '2']}");
 
        integer intRes = JsonRemoveValue(storeID, "Hello");   
        llOwnerSay("Remove result " + (string)intRes);
 
        intRes = JsonTestPath(storeID, "Hello");
        llOwnerSay("TestPath result " + (string)intRes);
    }
}

Advanced Functions

These are functions that allow scripts to receive notifications of values when they become available. This is useful for signalling between scripts or between scripts and region modules.

  • JsonTakeValue/JsonTakeValueJson
  • JsonReadValue/JsonReadValueJson

key requestID = JsonTakeValue(key storeID, string path)
key reqeustID = JsonTakeValueJson(key storeID, string path)

Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.

This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.

default
{
    state_entry()
    {
        key requestID = JsonTakeValue(storeID,"Event.Lock");
    }
 
    link_message(integer sender, integer ival, integer sval, key id)
    {
        if (sender != -1) return;
        if (id == requestID)
        {
            // we now have a "lock"
            llOwnerSay("read: " + sval);
 
            // release the "lock" by placing the value back in the store
            llSetValue(storeID,"Event.Lock",sval);
        }
    }
}

key requestID = JsonReadValue(key storeID, string path)
key reqeustID = JsonReadValueJson(key storeID, string path)

Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.

Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.

Examples

General
About This Wiki