Page 1 of 1

Help with JSON (again)

Posted: Thu Oct 29, 2020 2:58 pm
by em_uk
Hi PB'ers -

I have had a look on the forum and there's lots of posts regarding reading bits of JSON but nothing that I've been able to refer to to help do what I need: I have an exported JSON from with Tiled - I need to read the "layers" element, the pull out that data. I've tried freak's structurer creator but still cannot achieve what I need.

My Json looks like this which I load in from a file :

Code: Select all

{ "compressionlevel":-1,
 "editorsettings":
    {
     "export":
        {
         "target":"."
        }
    },
 "height":176,
 "infinite":false,
 "layers":[
        {
         "data":[2, 2, 2, 2, ... trimmed ],
         "height":176,
         "id":9,
         "name":"Map",
         "opacity":1,
         "type":"tilelayer",
         "visible":true,
         "width":160,
         "x":0,
         "y":0
        }, 
        {
         "draworder":"topdown",
         "id":2,
         "name":"Entities",
         "objects":[
                {
                 "height":16,
                 "id":63,
                 "name":"Start",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":32,
                 "y":144
                }, 
                {
                 "height":16,
                 "id":64,
                 "name":"Exit",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":208,
                 "y":144
                }, 
                {
                 "height":16,
                 "id":65,
                 "name":"Key",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":24,
                 "y":24
                }, 
                {
                 "height":16,
                 "id":66,
                 "name":"Time",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":928,
                 "y":120
                }, 
                {
                 "height":16,
                 "id":67,
                 "name":"undead",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":64,
                 "y":96
                }, 
                {
                 "height":16,
                 "id":72,
                 "name":"Bonus",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":224,
                 "y":24
                }, 
                {
                 "height":16,
                 "id":73,
                 "name":"Shield",
                 "rotation":0,
                 "type":"",
                 "visible":true,
                 "width":16,
                 "x":856,
                 "y":120
                }, 
				...etc 
I've tried copying the pointer structures to the arrays, but it only goes so deep.

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 4:11 pm
by infratec
I need the full file, or a correct JSON, not ...etc

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 4:18 pm
by cas
Next time, post smallest possible valid json that can be copy-pasted to pb editor so that we can test our code before posting it here to see if it works.

Code: Select all

EnableExplicit

Define raw_json.s = ~"{\"layers\":[{\"data\":[2,20,200],\"id\":1, \"height\":100},{\"id\":2,\"height\":500,\"objects\":[{\"x\":2,\"y\":4,\"name\":\"a\"},{\"x\":6,\"y\":8,\"name\":\"b\"},{\"x\":10,\"y\":12,\"name\":\"c\"},{\"x\":14,\"y\":16,\"name\":\"d\"}]}]}"
Define json_obj=ParseJSON(#PB_Any,raw_json.s)
If json_obj
  ;SetClipboardText(ComposeJSON(json_obj))
  Define layer_obj=GetJSONMember(JSONValue(json_obj),"layers")
  If layer_obj
    ;read first "layers" array element
    Define layer_first_entry=GetJSONElement(layer_obj,0)
    If layer_first_entry
      Debug "id: "+GetJSONInteger(GetJSONMember(layer_first_entry,"id"))
      Debug "height: "+GetJSONInteger(GetJSONMember(layer_first_entry,"height"))
      Define layer_first_entry_data=GetJSONMember(layer_first_entry,"data")
      
      Dim ddata(JSONArraySize(layer_first_entry_data)-1)
      ExtractJSONArray(layer_first_entry_data, ddata())
      Define i
      For i = 0 To ArraySize(ddata())
        Debug "data["+i+"]: "+ddata(i)
      Next i
    EndIf
    
    Debug "----"
    
    ;read second "layers" array element
    Define layer_second_entry=GetJSONElement(layer_obj,1)
    If layer_second_entry
      Debug "id: "+GetJSONInteger(GetJSONMember(layer_second_entry,"id"))
      Debug "height: "+GetJSONInteger(GetJSONMember(layer_second_entry,"height"))
      Define layer_second_entry_objects=GetJSONMember(layer_second_entry,"objects")
      
      Structure my_object
        x.i
        y.i
        name.s
      EndStructure
      
      NewList Objects.my_object()
      ExtractJSONList(layer_second_entry_objects, Objects())
      
      ForEach Objects()
        Debug "objects["+ListIndex(Objects())+"]: x="+Str(Objects()\x) + ", y=" + Str(Objects()\y)+", name="+Objects()\name
      Next
      
    EndIf
    
    
    ;Define layer_third_entry=GetJSONElement(layer_obj,2)
    ; ...
  EndIf
EndIf

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 4:58 pm
by infratec
You have to extend the structures ...

Code: Select all

Structure ObjectsStructure
  id.i
  x.i
  y.i
  height.i
  width.i
  visible.i
  name.s
  rotation.i
EndStructure

Structure LayersStructure
  id.i
  name.s
  List Data.i()
  List objects.ObjectsStructure()
EndStructure

Structure ExportStructure
  target.s
EndStructure


Structure EditorsettingsStructure
  export.ExportStructure
EndStructure


Structure TestStructure
  compressionlevel.i
  editorsettings.EditorsettingsStructure
  height.i
  infinite.i
  List layers.LayersStructure()
EndStructure


File = ReadFile(#PB_Any, "Test02.json")
If File
  Debug "File open"
  Format = ReadStringFormat(File)
  JSON$ = ReadString(File, Format|#PB_File_IgnoreEOL)
  Debug JSON$
  JSON = ParseJSON(#PB_Any, JSON$, #PB_JSON_NoCase)
  If JSON
    
    ExtractJSONStructure(JSONValue(JSON), @Test.TestStructure, TestStructure)
    Debug Test\compressionlevel
    Debug Test\editorsettings\export\target
    Debug Test\height
    
    Debug ""
    
    ForEach Test\layers()
      Debug "Layer: " + Str(Test\layers()\id) + " " + Test\layers()\name
      ForEach Test\layers()\Data()
        Debug "Data: " + Str(Test\layers()\Data())
      Next 
      ForEach Test\layers()\objects()
        Debug "Object:" + Str(Test\layers()\objects()\id) + " " + Test\layers()\objects()\name + " " + Str(Test\layers()\objects()\x) + "/" + Str(Test\layers()\objects()\y) + " " + Str(Test\layers()\objects()\width) + "/" + Str(Test\layers()\objects()\height)
      Next
      Debug ""
    Next
    
    FreeJSON(JSON)
  EndIf
  CloseFile(File)
EndIf

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 5:20 pm
by cas
It is impossible to do ExtractJSONStructure() on a whole json because "layers" is an array of objects, first and second object inside that array are not the same, and we do not see if there is 3rd object (or more) in that array and what theirs structures look. You must manually access each of them (GetJSONElement(), GetJSONMember(),...).

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 5:21 pm
by infratec
If they are not there, they are not filled. See data and objects.

If there is a type in every layer, then he can use an if to deside what he is showing.
But since the JSON is cutted ...

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 5:26 pm
by cas
Look again, "layers" array

first element:
{
"data":[2, 2, 2, 2, ... trimmed ],
"height":176,
"id":9,
"name":"Map",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":160,
"x":0,
"y":0
}
second element:
{
"draworder":"topdown",
"id":2,
"name":"Entities",
"objects":[
{
"height":16,
"id":63,
"name":"Start",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":32,
"y":144
},
{
"height":16,
"id":64,
"name":"Exit",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":208,
"y":144
},
{
"height":16,
"id":65,
"name":"Key",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":24,
"y":24
},
{
"height":16,
"id":66,
"name":"Time",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":928,
"y":120
},
{
"height":16,
"id":67,
"name":"undead",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":64,
"y":96
},
{
"height":16,
"id":72,
"name":"Bonus",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":224,
"y":24
},
{
"height":16,
"id":73,
"name":"Shield",
"rotation":0,
"type":"",
"visible":true,
"width":16,
"x":856,
"y":120
},
...etc
completely different structures, they do not have same key names.

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 5:29 pm
by infratec
Have you ever tried my version?
Is it working or not?

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 6:36 pm
by em_uk
Thanks guys, just catching up now.

If you want the full json its here - I have truncated the data in line 13 because its pretty large

https://pastebin.com/74aPP5Gm

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 6:51 pm
by em_uk
infratec wrote:Have you ever tried my version?
Is it working or not?
Thanks guys - both do work on my test data. That's helped me understand how you read into the object data.

Re: Help with JSON (again)

Posted: Thu Oct 29, 2020 9:20 pm
by infratec
Download is 'forbidden'.
But if it works for you, it's not neeed.