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: 
Fenda
Level 7

roSGNode children and findNode

I have a fairly large associative array of data that I would like to convert to a Node Tree as recommended by the SDK docs. However, I cannot seem to get roSGNode children and findNode to play nicely together. Below is a snippet I have been using for testing. Any thoughts?

obj = createObject("roSGNode", "Node")
child = createObject("roSGNode", "ContentNode")
child.id = "foo"
obj.appendChild(child)
print obj.findNode("foo") ' This returns Invalid
0 Kudos
7 Replies
Roku Employee
Roku Employee

Re: roSGNode children and findNode

Brightscript Debugger> obj = createObject("roSGNode", "Node")
child = createObject("roSGNode", "ContentNode")
child.id = "foo"
obj.appendChild(child)
print obj.findNode("foo") ' This returns Invalid

Brightscript Debugger>
Brightscript Debugger>
Brightscript Debugger>
Brightscript Debugger> <Component: roSGNode> =
{
change: <Component: roAssociativeArray>
focusable: false
focusedChild: <Component: roInvalid>
id: "foo"
}


Works for me. I'll go on a limb here... are you trying to do that before calling .show() on roSgScreen? I won't be surprised if it fails then.
0 Kudos
ChrisDP
Level 7

Re: roSGNode children and findNode

obj = createObject("roSGNode", "Node")
child = createObject("roSGNode", "ContentNode")
child.id = "foo"
obj.appendChild(child)
print obj.findNode("foo")
' invalid '
print obj.getChildCount()
' 1 '
print obj.getChild(0)
' <Component: roSGNode> = '
' { '
'     change: <Component: roAssociativeArray> '
'     focusable: false '
'     focusedChild: <Component: roInvalid> '
'     id: "foo" '
' } '

When testing I tried the above and found that appendChild() does appear to be adding the child to the obj but findNode() dose not find it. I did some more testing such as:
obj = createObject("roSGNode", "Node")
child = obj.createChild("ContentNode")
child.id = "foo"
print obj.findNode("foo")
print obj.getChildCount()
print obj.getChild(0)


I also got the same results again. 
Finally I tried to create the obj node using m.top.createChild() and it worked:
obj = m.top.createChild("Node")
child = createObject("roSGNode", "ContentNode")
child.id = "foo"
obj.appendChild(child)
print obj.findNode("foo")
' <Component: roSGNode> = '
' { '
'     change: <Component: roAssociativeArray> '
'     focusable: false '
'     focusedChild: <Component: roInvalid> '
'     id: "foo" '
' } '
print obj.getChildCount()
' 1 '
print obj.getChild(0)
' <Component: roSGNode> = '
' { '
'     change: <Component: roAssociativeArray> '
'     focusable: false '
'     focusedChild: <Component: roInvalid> '
'     id: "foo" '
' } '


All tests where done after:
screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
screen.setMessagePort(m.port)
scene = screen.CreateScene("Main")
screen.show()

This leads me to believe this may be a bug of some sort.
Christopher Dwyer-Perkins
Developer, REDspace
redspace.com
0 Kudos
Roku Employee
Roku Employee

Re: roSGNode children and findNode

@ChrisDP - model#? firmware#?
which thread are you trying findNode() in? (render thread, task thread, main() thread)
0 Kudos
Fenda
Level 7

Re: roSGNode children and findNode

So, it does seem to work when I place this in main(). The correct object is printed to the telnet logs.



Sub Main(args)
  m.screen = CreateObject("roSGScreen")
  m.screen.setMessagePort(Legacy().getMessagePort())
  m.scene = m.screen.CreateScene("MainScene")
  m.screen.show()

  obj = createObject("roSGNode", "Node")
  child = createObject("roSGNode", "ContentNode")
  child.id = "foo"
  obj.appendChild(child)
  print obj.findNode("foo")


The original code that wasn't working was inside a component extending Group and in a runtime function and so I suppose it was in the render thread? Switching the first line of code to that  suggested by @ChrisDP fixed this though. Is this how we're expected to create the initial Node in a Node Tree?

obj = m.top.createChild("Node")
0 Kudos
ChrisDP
Level 7

Re: roSGNode children and findNode

"RokuNB" wrote:
@ChrisDP - model#? firmware#?
which thread are you trying findNode() in? (render thread, task thread, main() thread)

model# 4630x - Roku Premiere+
firmware# 7.7.0 - build 4094-29
This was on the render thread and was executed inside a component extending Group and in a runtime function like @Fenda.
Christopher Dwyer-Perkins
Developer, REDspace
redspace.com
0 Kudos
bird3214
Level 7

Re: roSGNode children and findNode

Hi,
I have the same issues:
Brightscript Debugger> node = CreateObject("roSGNode", "ContentNode")

Brightscript Debugger> child = CreateObject("roSGNode", "ContentNode")

Brightscript Debugger> child.id = "aaa"

Brightscript Debugger> node.appendChild(child)

Brightscript Debugger> ?node.findNode("aaa")
invalid

Brightscript Debugger> ?node.getChild(0)
<Component: roSGNode:ContentNode> =
{
    change: <Component: roAssociativeArray>
    focusable: false
    focusedChild: <Component: roInvalid>
    id: "aaa"
}

Brightscript Debugger> m.top.appendChild(node)

Brightscript Debugger> m.top.removeChild(node)

Brightscript Debugger> ?node.findNode("aaa")
<Component: roSGNode:ContentNode> =
{
    change: <Component: roAssociativeArray>
    focusable: false
    focusedChild: <Component: roInvalid>
    id: "aaa"
}


It seems that pointer to child element is not set correctly before node is appended to m.top. Attaching and detaching node fixes the pointer, but it should work out of box.
0 Kudos
Roku Employee
Roku Employee

Re: roSGNode children and findNode

"bird3214" wrote:
It seems that pointer to child element is not set correctly before node is appended to m.top. Attaching and detaching node fixes the pointer, but it should work out of box.

ah... i vaguely seem to remember that perhaps search is always done from m.top (i.e. current component context) down. Check in the docs, maybe it's between the lines.
0 Kudos