JsonApiStruct Usage
JsonApiStruct is scripted object with support to:
- Encode script object/ variable to JSON format
- Decode data from JSON format onto script object/ variable
- Import/export from/to file
- Import/export from/to string
It can also be used as callback object when handling responses from Backend API (script) where incoming data are automatically expanded.
How To
- Create your own class by inheriting JsonApiStruct
- Register all variables you require in constructor of object
- Create hierarchy from objects if you need more complex structures
Simple Declaration
// Example object
class MyObject : JsonApiStruct
{
string name;
string year;
void MyObject()
{
// these variables will be converted to JSON or filled from JSON
RegV("name");
RegV("year");
}
}
Hierarchy Declaration
// Child 1
class MyName : JsonApiStruct
{
string name;
void MyName()
{
RegV("name");
}
}
// Child 2
class MyFloats : JsonApiStruct
{
float float1;
float float2;
void MyFloats()
{
RegV("float1");
RegV("float2");
}
}
// Parent structure
class MyParent : JsonApiStruct
{
MyName name;
MyFloats floats;
void MyParent()
{
RegV("name");
RegV("floats");
}
}
File Operations
You can store you object into file (ie. invoke Pack + Save to file) or you can just save already packed JSON (Save to File).
File Import
// unpack from RAW data - either put data there manually (JSON!) or it is callback result
void UnpackFromRAW(string data)
{
Dummy dummy = new Dummy(); // Dummy extends JsonApiStruct
dummy.ExpandFromRAW(data);
// pack + create file at once
dummy.SaveToFile("dummy_test.json");
}
// call OnPack() and save result into file
void PackAndSaveLocally()
{
dummy.PackToFile("dummy_test.json");
}
File Export
void LoadJSON()
{
Dummy dummy = new Dummy(); // Dummy extends JsonApiStruct
dummy.LoadFromFile("dummy_test.json"); // now dummy object is hydrated with json data
// note that Expand is automatically called upon object
// you can also use its data as string
Print(dummy.AsString());
}
Packing
Packing is fairly easy, when object is either asked by thread/callback or invoked manually to pack its data, the OnPack()
event method is called.
Automated Packing/Expanding
To make things easier, it is possible to work with a JSON object just by registering variables and object into JsonApiStruct.
What Works | What Doesn't |
---|---|
|
|
// Child
class MyChild : JsonApiStruct
{
// object example
}
// Parent
class MyParent : JsonApiStruct
{
string name;
string year;
MyChild obj1;
void MyParent()
{
obj1 = new MyChild();
// this register variables for auto use
RegV("name");
RegV("year");
RegV("obj1");
}
}
// Create JSON and print to console
void PackExample()
{
MyParent dummy = new MyParent();
// variables will be default unless set to something reasonable
dummy.name = "King Henry VIII";
dummy.year = 1509;
// create JSON
dummy.Pack();
// print result data to console as string
Print(dummy.AsString());
}
// Load from existing file in JSON format
void LoadAndExpandExample()
{
MyParent dummy = new MyParent();
dummy.LoadFromFile("dummy_test.json");
// now json is upon dummy object
// note that Expand is called automatically upon object and all variables registered!
// no additional scripting required unless you want to handle something specific or debug perhaps
// you can also use it's data as string
Print(dummy.AsString());
}
Variables
// assuming you have variables declared upon JsonApiStruct itself!
float m_MyFloat;
// add simple variable
void OnPack()
{
StoreFloat("MyFloat", m_MyFloat);
}
Objects and Variables
// assuming variables are declared upon JsonApiStruct itself
float m_MyFloat;
int m_MyInt;
protected ref AvatarStruct m_Avatar; // AvatarStruct extends JsonApiStruct
// add object and several variables
void OnPack()
{
StoreFloat("MyFloat", m_MyFloat);
StoreInt("MyInt", m_MyInt);
StoreObject("avatar", m_Avatar);
}
If the OnPack()
event method is declared upon children objects, it is called upon them hierarchically as well.
// assuming the array is declared upon JsonStruct itself
protected ref array<string> m_array = {};
// add array and its items
void OnPack()
{
StartArray("m_array");
for (int i = 0, count = m_array.Count(); i < count; i++)
{
ItemString(m_array[i]);
}
EndArray();
}
Error Handling
If you use object as a callback and an error happen during JSON processing, it generates events upon that very object:
class Dummy : JsonApiStruct
{
void OnExpand()
{
// Event when expand (unpack) process starts
// if you want to handle something before process starts (init/clear variables for example)
}
void OnBufferReady()
{
// this is called after successfull JSON pakc process
// if you want the buffer's finalised string for any purpose
}
void OnSuccess(int errorCode)
{
// errorCode is EJsonApiError
// Event called when pending store operation is finished - callback when all went as expected
}
void OnError(int errorCode)
{
// errorCode is EJsonApiError
// Event called when pending store operation is finished - callback when error happened
}
}
Error Codes
As defined in EJsonApiError:
Code Enum | Description |
---|---|
ETJSON_UNKNOWN | General error - not implemented |
ETJSON_OK | This is generated upon sucessfull processing at onSuccess() event |
ETJSON_COMMSEND | Sending of object failed (callback got error code) |
ETJSON_COMMRECV | Receiving of object failed (callback got error code) |
ETJSON_PARSERERROR | Parsing process failed - invalid data or corrupted format? |
ETJSON_PACKNOSTART | Packing process cannot start - invalid state or other problems |
ETJSON_TIMEOUT | Failed to send data due to timeout (when JsonStruct data is sent via RestApi or BackendApi |
ETJSON_NOBUFFERS | Too many objects processed at once! |
ETJSON_FAILFILELOAD | Could not load file with JSON data |
ETJSON_FAILFILESAVE | Could not save file with JSON data |
JSON Validation
JSON validation allows to test the input/output values.
Result structure can be used as input as well and it should match in the end, similar process can be used for verifying already existing structures.
// root structure example
class DummyRoot : JsonApiStruct
{
// content + pack/expand methods
}
DummyRoot dummy = new DummyRoot();
dummy.Pack(); // pack content
string data1 = dummy.AsString(); // get packed JSON #1
dummy.ExpandFromRAW(data1); // load structure once more from data!
// repeat process :-)
dummy.Pack(); // pack content
string data2 = dummy.AsString(); // get packed JSON #2
// now both can be visualised
Packing object will produce a long, non-formatted string like:
{"m_bool":false,"m_int":1024,"m_double":1.2345678806304932,"m_string":"Hello I am your new string!","m_objects":{"obj1":{"name":"Van Ceulen","year":"1706","val":3.1415927410125734},"obj2":{"name":"Bernoulli","year":"1683","val":0.5772156715393066},"obj3":{"name":"Feidius","year":"430BC","val":1.6180340051651}}}
Use suitable online/other tool for readable structure, result can be stored to textfile and compared by binary/text compare tool if neccessary.