Your Digital Media Has Never Looked So Good

 
parag
Topic Author
Posts: 14
Joined: Fri Mar 24, 2017 7:07 am

Copy of Brightscript object being created when using assignment operator.

Tue Apr 18, 2017 10:29 am

In my main.brs, I am parsing a JSON from server and then assign the result which is an associative array with more nested associative arrays which house more arrays.

json = ParseJSON()
m.scene.json = json

Now, what I would expect is that it m.scene.json should be a reference to json since it is not an intrinsic object and not a copy, but a copy is being created. Any changes I make to 'json' now don't show up in m.scene.json and hence my assumption that it is a copy and not a reference. Also, after the assignment, m.scene.json become immutable and any additions that I make to the associative array fail silently.

Any ideas what I am doing wrong and what I should be doing instead?
 
User avatar
RokuNB
Posts: 38
Joined: Fri Mar 31, 2017 2:22 pm

Re: Copy of Brightscript object being created when using assignment operator.

Tue Apr 18, 2017 3:34 pm

RSG thinks different than Brightscript.
dot-access for nodes (i.e. myNode.myField) gets converted to a setValue/getValue call (depending on which side of assignment that is) and these i think always assign composite objects like roAssociativeArray and roArray "by value", in result doing deep-copy for your JSON. Nodes are assigned by reference.

When you do
m.scene.json.a = 7
the m.scene gets the node, m.scene.json returns a deep copy of the dictionary, then .a = 7 adds/assigns a key-value pair - but this is a different copy that gets modified. At the end of that statement, this copy gets disposed since nobody needs it anymore - the original m.scene.json however remains unmodified (hence "read-only")
 
parag
Topic Author
Posts: 14
Joined: Fri Mar 24, 2017 7:07 am

Re: Copy of Brightscript object being created when using assignment operator.

Wed Apr 19, 2017 7:52 am

Thank you for your prompt response. It does clear why I seemingly had an immutable copy. But, how do I go about making changes which are persisted? Would it make sense to parse the JSON inside a new task and then assign it to the scene, but I am assuming that I will end up at the same place.

Also, if I am in the node and try to access json using m.top.json, would I get a copy again as opposed to the reference because that is what is happening currently.
 
User avatar
RokuNB
Posts: 38
Joined: Fri Mar 31, 2017 2:22 pm

Re: Copy of Brightscript object being created when using assignment operator.

Wed Apr 19, 2017 11:39 am

The response i have heard has been to use ContentNodes instead, i.e. rebuild your structure using ContentNode (or even Node if no media metadata) as a foundation for your nested structures. And that makes total sense if the data you have is either (a) multimedia item info or (b) will be used for RSG API calls (most components ask for their collections in ContentNode form).

Note that Node (roSgNode) components are passed by reference because of multi-thread-safe mechanism in them. So if convenient, their use is more efficient than deep copies.

Also note that inside a component script you could (and probably should) use the self/this variable `m` to store and mutate complex {}/[] structures.
 
parag
Topic Author
Posts: 14
Joined: Fri Mar 24, 2017 7:07 am

Re: Copy of Brightscript object being created when using assignment operator.

Fri Apr 21, 2017 7:56 am

So, if I am getting this correctly, I should use a ContentNode for a field in the scene. Would that be different from using associative array? Would that not be immutable? Or am I completely off base?

To add to the above question, I tried the following sequence of steps

HomeScene.xml

<component name="HomeScene" extends="Scene"  xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">
    <interface>
        <!-- <field id="json" type="assocarray" /> -->
       <field id="json" type="node" />


In main.brs

    m.scene.json = createObject("roSGNode", "ContentNode")

    m.scene.json.addFields({title: json.reftitle, contentList:json.contentList, backgroundUrl:json.backgroundUrl})


ContentList is an roArray type. So, while I can change the title, I can't make any changes to for ex the title field in the associative array in the ContentList array or add another item to the array. Should all the hierarchical components if they are not of intrinsic types be a ContentNode? Thanks.
 
User avatar
RokuNB
Posts: 38
Joined: Fri Mar 31, 2017 2:22 pm

Re: Copy of Brightscript object being created when using assignment operator.

Sat Apr 22, 2017 4:26 pm

parag wrote:
So, if I am getting this correctly, I should use a ContentNode for a field in the scene. Would that be different from using associative array? Would that not be immutable? Or am I completely off base?
[...]
ContentList is an roArray type. So, while I can change the title, I can't make any changes to for ex the title field in the associative array in the ContentList array or add another item to the array. Should all the hierarchical components if they are not of intrinsic types be a ContentNode? Thanks.

Using Node or ContentNode field to hold your data is different that using roAA/roArray in that yes, from your point of view node fields are mutable "in place". And yes, if you want to modify your complex structures in place, you should use Node/ContentNode instead of roAA/roArray. Would it help if in the context of node fields only you think about arrays/dictionaries as "by value" primitive types - and all roSgNode subtypes as "by reference" objects?

Why are you not using the component's `m` variable? Is it because you want to mutate a complex structure from outside?
 
parag
Topic Author
Posts: 14
Joined: Fri Mar 24, 2017 7:07 am

Re: Copy of Brightscript object being created when using assignment operator.

Mon Apr 24, 2017 4:17 am

RokuNB wrote:
parag wrote:
So, if I am getting this correctly, I should use a ContentNode for a field in the scene. Would that be different from using associative array? Would that not be immutable? Or am I completely off base?
[...]
ContentList is an roArray type. So, while I can change the title, I can't make any changes to for ex the title field in the associative array in the ContentList array or add another item to the array. Should all the hierarchical components if they are not of intrinsic types be a ContentNode? Thanks.

Using Node or ContentNode field to hold your data is different that using roAA/roArray in that yes, from your point of view node fields are mutable "in place". And yes, if you want to modify your complex structures in place, you should use Node/ContentNode instead of roAA/roArray. Would it help if in the context of node fields only you think about arrays/dictionaries as "by value" primitive types - and all roSgNode subtypes as "by reference" objects?

Why are you not using the component's `m` variable? Is it because you want to mutate a complex structure from outside?

I am using 'm', but also want to mutate the structure from outside. What I have is a json containing a list of groups and each group has a list of videos. So, the HomeScene in this case has the parsed JSON (m.scene.json) and now when the user clicks on a video, I display the video details with a Play button. When user clicks on Play, I start playing the video, but I also want to add the video reference/details to the 'Recents' section in the parsed JSON which is where I am having trouble since my parsed copy is now immutable.
Also, if I am using Node/ContentNode, am I correct in assuming that anything that I want to stay mutable in the nested structure which is not an intrinsic type should also be a Node/ContentNode?

Who is online

Users browsing this forum: No registered users and 12 guests