[plugin] JSON (import/export/generate/edit/inspect/...)

Post your work in progress addons and get feedback

Post » Sun Apr 06, 2014 8:54 pm

@vtrix
it will obviously (:
B
66
S
22
G
14
Posts: 1,484
Reputation: 16,511

Post » Thu Apr 10, 2014 11:40 pm

@Yann

i have some trouble resetting the current path, from certain paths (well thats what i think is happening)

edit: i tried to change the path in a current loop, and continue the loop at this path, but this doesn't work
i think i just need to call a new function

no, i still have troubles..
my only conclusion is that you cant switch path when in a for each current, its somehow stuck at that path,
and my loop starts with a set path/reset, and runs one perfect, but is then stuck at end path

its like "currentpath" has its own variable that isn't reset when set current path to root
ImageImage
B
70
S
21
G
7
Posts: 827
Reputation: 10,052

Post » Fri Apr 11, 2014 5:21 pm

@Yann

i made a capx of the problem,
https://dl.dropboxusercontent.com/u/61666915/jsonProblem.capx

use console to check the values, so i run the same function twice,
at begin of the function i have a set path, but on second run, the path seems wrong, while it should been reset
ImageImage
B
70
S
21
G
7
Posts: 827
Reputation: 10,052

Post » Fri Apr 11, 2014 10:55 pm

@vtrix
Ok very interesting. At first I thought it was just a simple misuse, but it turned out there were a very peculiar issue.

So first for the misuse, which is more of a design flaw for now, is that the foreach loop is actually modifying the current path to point to the property being foreached ( which doesn't work properly if you loop using an root based path (the loop will ignore the path <_<)). So, if you modify the current path inside the foreach loop, everything can get fucked up (:

Here is one example case:
considering this object:
Code: Select all
{ "Wizard": {
      "stats":{
         "hp":100,
         "mp":80,
         "int":120,
         "dex":20,
         "str": 10
      },
      "buffs": {
         "hp":10,
         "mp":15,
         "int":10,
         "dex":3,
         "str": 2
      }
   }
}


Let say we want to loop through all the property and display their stats + buffs. It could be done like that:
Code: Select all
-> System: set Current Path to root["Wizard","stats"]
+ JSON: foreach current[]  // using foreach root["Wizard","stats"] is broken
  Local text property = ""
  Local number value = 0
  -> System: set property to JSON.CurrentKey
  -> System: set value to JSON.Value(1,CurrentKey)
  -> System: set Current Path to root["Wizard","buffs"] // here you are modifying the looping path
  -> Text: Set text to property & ":" & value& " + " & JSON.Value(1) & " = " & value+ JSON.Value(1)


Here is what will be output in the text object:
Code: Select all
hp:100 + 10 = 110
mp:15 + 15 = 30
int:10 + 10 = 20
dex:3 + 3 = 6
str:2 + 2 = 4

As you can see, after the first iteration, the loop is in fact looking into the buffs path
and if you doesn't have the same properties in the two path you'll get some NaN or undefined values.

I see two possible solutions to this problem:
1. have a separated Current Path and Loop Path. As much as it makes sense now, I think it's a very confusing solution. What would be the current[] in this situation? or maybe I should have root/current/loop... And what happens with nested loops? should I name those path like it's done with for loops and loopindex?... So yeah I'm not too sure about this idea
2. have the loop reset the Current Path to the original path after each iterations. Good thing is, it's simple and straightforward to implement and use. Bad thing is, any change to the current path you do inside a loop will be lost at the end of the iteration (cannot be saved for later). But I think it's a very specific case and I can easily find a work around using an array in C2 and making a "savePath" and "buildPath" function.
Code: Select all
// Function.Call("loadPath")
+ Function: On "loadPath"
   -> JSON: Set Current Path to root[]
   + Array: For each X element
      -> JSON: Set Current Path to current[Array.CurValue]
Code: Select all
// Function.Call("savePath","path","you","want","to","save",...)
+ Function: On "savePath"
   -> Array: Set size to (0,1,1)
   + System: Repeat Function.ParamCount times
      -> Array: Push back Function.Param(loopindex) on X axis

Though one weakness is that you can't dynamically save the path because you have no way, during a foreach loop, to know the entire path, you just know the CurrentKey. If you are recursively inspecting an entire unknown JSON it's harder to save a spacific path (probably doable if you save the path constantly during the recursion...)
Maybe I could add a "foreach Node in the path"condition you could call in savePath instead of passing parameters.

Anyway, now, for the real interesting stuff I discovered thanks to your capx:
1. The list of parameters you pass in set Current Path to root["template","folder"], which is internally an array, is in fact built just once, and the same array object is passed over and over each time C2 reaches this action (at least during a given tick).
And the plugin was using this very same array as a current path, and this array was modified when going through your two first foreach.
That's why when you execute the run function a second time, you are already at root["template","folder","object1","path"] instead of root["template","folder"]. The array of argument was modified during the previous run.
Hopefully this is easily solvable by using a copy of this array.
2. A the end you logged properties (0, 1, 2, 3, 4 ,5 ,6) that didn't really make sense since there were no array in your JSON. And the reason for that is that, in the second run, your first foreach was looping through the value at ["template","folder","object1","path"] which was actually the string "folder2". Javascript often consider strings as arrays of character, so you where looping through the 7 letters and was logging their indices. (which is more an unexpected feature than a bug :D)
B
66
S
22
G
14
Posts: 1,484
Reputation: 16,511

Post » Sat Apr 12, 2014 2:43 pm

@Yann , thanks for checking, yes a couple of things

setting path and running thru current seems the most logical thing to do, if you know the correct way to do so, i dont think a root foreach would be that much use, setting the root outside the foreach loop is what i eventually did and works great.

is also made the mistake that when importing a json file i didn't make a root object, this somehow also screws things up, not sure if thats also in my capx example, but the structure looks fine a first sight (there's also a root object) but i think its not recognised as such.

as first time user, working with the json plugin (json for that matter), i found the 0 and 1 for value, the most confusing (at start) as you have the currentKey but not currentValue + the naming order, a path has to exist but a key doesn't, as in.. you set the key at a nonexistend name, you don't have to create it like an object (and this also creates a path) and an object you create and set

edit: if you return an arrayProperty in for each, the arrayposition is a string, that can be confusing..

as for path saving, i had the same idea, also if you could save the path, you probably are most likely to want to save a path to an array or object,
you could create a json path "folder" filled with arrays at firstrun, and name them "key" & "path" , but indeed if you don't know the structure, indicating what the path is, would be harder i guess, on the other side json is very fast so iterating thru the structure is already fast and some shortcuts can always been made

when im there, i will try those function out, i like the function.paramCount one :)
ImageImage
B
70
S
21
G
7
Posts: 827
Reputation: 10,052

Post » Wed Apr 16, 2014 10:54 am

Hello there,
I just stumbled upon this plugin and it seems to be amazing for my project!

But, as I'm not currently able to try it, I was wondering if there is a way to get a random item from a structure.

For example:
Code: Select all
{
   "item 0" : {
      "feature 0" : "value",
      "feature 1" : "value"
   },
   "item 1" : {
      "feature 0" : "value",
      "feature 1" : "value"
   }
}

is it possible to get a random item with something like:
Code: Select all
JSON.Value(0, floor(random(0, 1)))


In other words: are nodes' indexes numbered too or should I replace "item 0" and "item 1" with 0 and 1 and call it a day?
B
6
S
2
G
1
Posts: 6
Reputation: 513

Post » Wed Apr 16, 2014 5:04 pm

@Copons , instead of making the root an object, make it an array, this supports indixes or you could index the objects itemnames in a seperate array
ImageImage
B
70
S
21
G
7
Posts: 827
Reputation: 10,052

Post » Wed Apr 16, 2014 7:02 pm

@vtrix ah nice!
For some reasons the online JSON editor I was using gave me errors all over the place if I tried to make arrays of objects, so I just assumed it wasn't a thing in JSON, but reading your answer I read some JSON syntax references and it is possible and actually really easy:
Code: Select all
[
    {"key1" : "val1"},
    {"key2" : "val2"}
]



Thank you very much! :)
B
6
S
2
G
1
Posts: 6
Reputation: 513

Post » Thu Apr 17, 2014 9:22 pm

@vtrix , @shinkan (mostly highlighting you since you were the most active (: )

New version: JSON v1.1
The first post documentation has been updated to reflect this change

ChangeLog
v1.1 - 2014-04-17
    - implement save/load/debugger
    - ToJson deprecated and replaced by AsJson for overall coherence
    - change the brackets syntax for a less confusing one (I hope)
    Code: Select all
    before: root["Wizard","stats","hp"]
    after:  [email protected]"Wizard","stats","hp"
    - change Length for Size and handle object/array return -1 for anything else
    - isEmpty condition and Clear action for array and object
    - add a CurrentValue property
    - in foreach loop reset the current path to the path given at the begining on each iteration, this way we can mess with this current path to our heart content within the loop
    - more reliable logData

Have fun testing :D

If all go well, I'll probably move it to completed plugin.
B
66
S
22
G
14
Posts: 1,484
Reputation: 16,511

Post » Thu Apr 17, 2014 9:33 pm

woah, nice :D
ImageImageImageImage
B
157
S
66
G
41
Posts: 2,598
Reputation: 34,823

PreviousNext

Return to Work in Progress Addons

Who is online

Users browsing this forum: No registered users and 0 guests