Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
EnTerr
Level 8

Cheap thrills with SG Node

I was playing with SGt Nobby Nobbs^ and here are couple of not-so-amusing observations:
BrightScript Debugger> screen = CreateObject("roSGScreen")
BrightScript Debugger> g = screen.getGlobalNode() : g.addField("aa", "assocarray", false) : g.aa = { } : ? g.aa
<Component: roAssociativeArray> =
{
}
BrightScript Debugger> g.aa.x = 7 : ? g.aa
<Component: roAssociativeArray> =
{
}           ' Dude! Where is my 7 ?'
BrightScript Debugger> recurse = { }: recurse.d = recurse : g.aa = recurse
           ' and... Roku is dead as a doornail! it wouldn't react to Home nor reboot on it's own

First one is that updating AA in a field does not work nor cause an error. The second one is the player going in coma (to my disappointment, not even YAWRR - had to manually punch Konami reboot). I think i understand them both but these are on the other side of "normal"

(^) get it? anyone?
0 Kudos
5 Replies
TheEndless
Level 7

Re: Cheap thrills with SG Node

I'm not sure if it's explicitly documented anywhere, but the explanation for the first issue can be gleaned from the new "Task Node Changes In Firmware Version 7.2" section here: https://sdkdocs.roku.com/display/sdkdoc ... ph+Threads
In firmware version 7.2, on each transition of the Task node control state to "RUN", the render thread m is cloned, the original is passed to the new Task node thread, and the render thread retains the clone. Members of m which are basic types like integers, Booleans, strings, and floats are cloned. Associative arrays and arrays are cloned recursively. RoSGNodes are also cloned, but not recursively, since they are already thread-safe. This is all much like what would happen when an associative array is set to a field.

Associative arrays that are stored in Node fields are cloned both on set and get, so you're not operating on the original AA. The only way to modify it would be to clone it to a local variable, change the value, then reset the "aa" field... All of which has obvious performance implications.
aa = g.aa : aa.x = 7 : g.aa = aa : ? g.aa

Interestingly, in the above line of code, the AA is cloned on three separate occasions... once when retrieved and stored in the local variable, again when reset to the local variable, and yet again when printed to the console.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
EnTerr
Level 8

Re: Cheap thrills with SG Node

"TheEndless" wrote:
aa = g.aa : aa.x = 7 : g.aa = aa : ? g.aa

Interestingly, in the above line of code, the AA is cloned on three separate occasions... once when retrieved and stored in the local variable, again when reset to the local variable, and yet again when printed to the console.

Now that you put it this way, this is...

Given multi-megabyte nested data structures and the lack of other means of data sharing, causing transparent deep-copy on each innocent dotting... what were you RokuCo guys thinking?! Are you trying to alienate developers? Good ones will sneer at it - bad ones won't even know it's there, only see how "slow" and crashy Roku is and the word will keep spreading
0 Kudos
TheEndless
Level 7

Re: Cheap thrills with SG Node

"EnTerr" wrote:
Given multi-megabyte nested data structures and the lack of other means of data sharing, causing transparent deep-copy on each innocent dotting... what were you RokuCo guys thinking?!

I believe it's a paradigm shift of sorts. SceneGraph is intended to be fundamentally node based. If you have that large of a data set that needs to be used in SceneGraph, then you'd want to use a ContentNode instead, as they are passed around by reference. A ContentNode, by default, includes all of the fields defined in the Content Metadata section of the documentation (as well as a few other undocumented fields, as I've discovered). If you need additional fields, then you'd need to create a custom ContentNode that extends the base ContentNode and add the new fields via the <interface /> element.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
EnTerr
Level 8

Re: Cheap thrills with SG Node

"TheEndless" wrote:
I believe it's a paradigm shift of sorts. SceneGraph is intended to be fundamentally node based. If you have that large of a data set that needs to be used in SceneGraph, then you'd want to use a ContentNode instead, as they are passed around by reference. A ContentNode, by default, includes all of the fields defined in the Content Metadata section of the documentation (as well as a few other undocumented fields, as I've discovered). If you need additional fields, then you'd need to create a custom ContentNode that extends the base ContentNode and add the new fields via the <interface /> element.

Not quite a paradigm shift, methinks.
SG is good as a View but lacks both in Model (data) and Controller (adding functions) in MVC sense. Padding ContentNode is a decent hack for simple values - but what when having deep multi-MB hierarchical data to deal with (cue MRSS, MRSA and other infections)? The issue is still there, since eventually have to use that dot "." (`getField()/setField()` in disguise, you know what i mean) and major memory churn happens every time. And what if said data is a graph with cycles? (cue the 2nd thrill above, SG dies)
0 Kudos
EnTerr
Level 8

Re: Cheap thrills with SG Node

As an update, seems rOS 7.2 has solved the "curse of recursed data" issue, where cycles in the data assigned to a node field was wedging the player. 

Now field assignment takes recursive structures like a champ! And i mean they get marshaled properly, meaning the value in the field remains recursive and e.g. would make formatJSON() burp a "BRIGHTSCRIPT: ERROR: FormatJSON: Nested object reference" colon-centipede.
0 Kudos