Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
btpoole
Channel Surfer

rsgNode & Task

Is it possible to pass the rsgNode to a task? I have a rgsnode for a grid that is populated by a parse that has to be executed in a task. The code is not actually in the task but is in a function included in the task.  Part of the function references the rsgNode of the grid for such things as column widths, itemfocus and others,  The code looks something like the following.  I need to finda a way to pass the m.programmarkupgrid to the task to be referenced in the function. I can't just run the function without execution timeout. Thanks for any help

step1.brs
function prearray()
m.ContentTask_preslot = createObject("RoSGNode","GridContent")
m.ContentTask_preslot.array1=m.array1data
m.ContentTask_preslot.array2=m.array2data
m.ContentTask_preslot.array3=m.array3data
m.ContentTask_preslot.ObserveField("state", "pre_grid")
m.ContentTask_preslot.control = "RUN"
end function

function setGridContent()
?"in setGridContent--"
m.array1=m.top.array1
m.array2=m.top.array2
m.array3=m.top.array3
gridx=1
rows=0
temp=[]

m.programmarkupgrid.numColumns= m.array3
?"NUMBER OF COLUMNS>>>>>>>>>>>>>>>>>>>>>>>>> "m.programmarkupgrid.numColumns
for i = 0 to m.programmarkupgrid.numColumns
temp[i]=312
end for
m.programmarkupgrid.columnwidths=temp
end function





mytask.xml
<?xml version="1.0" encoding="UTF-8"?>
<component name="GridContent" extends="Task">

  <interface>
        <field  id = "array1"  type = "roArray" />
      <field id = "array2"   type = "roArray" />
     <field id = "array3"   type = "roArray" />
    </interface>
    <script type="text/brightscript" uri="pkg:/source/step1.brs" />
 
<script type="text/brightscript">
<![CDATA[

sub init()
    m.top.functionName = "taskRun"
end sub

function taskRun() as void
?"in GridContent Task"
setGridContent()
end Function


  ]]>
  </script>
</component>
0 Kudos
9 REPLIES 9
destruk
Binge Watcher

Re: rsgNode & Task

I'd add a field to the task interface - that way you can store your value into that field and the task can play with it.
Yeah, just tested, that works.
For your xml interface field add --
 <field id="share" type="node" />

That will allow you to throw a value to the task node using the share field for an roSGNode object.
0 Kudos
btpoole
Channel Surfer

Re: rsgNode & Task

Passing the individual fields not a problem, was wondering if the rsgnode could be visible to the task as a whole. I guess from what I have tried only the individual fields can be passed.
Thanks any way
0 Kudos
destruk
Binge Watcher

Re: rsgNode & Task

I don't think I understand what your concern is.
In your main scenegraph thread you can grab any node in the app by doing a m.mynodeineed=m.top.findnode("id name") provided it is specified in the xml markup as a required object to load - and then you can access it and modify anything it contains or displays or controls from that main scenegraph thread.
In the component threads you can grab any node from the main app by doing a m.mynodeineed=m.global.findnode("id name") - provided it has been loaded in the main thread (AFIK?) and then you can access it and modify anything it contains or displays or controls from that component thread.
In the component or task threads, if something is specified in its own xml, you would use m.top.findnode to grab it and utilize it.
The individual values of a node, once you have found it, can be edited anywhere.

Just how many items are you trying to parse or build here?

Would this code make any sense to you?
<?xml version="1.0" encoding="UTF-8"?>
<!-- ***** gridcontent.xml ***** -->
<component name="GridContent" extends="Task">

<interface>
<field id="array1" type="roArray" />
<field id="array2" type="roArray" />
<field id="array3" type="roArray" />
<!-- added status field which will notify observers every time the value changes -->
<field id="status" type="string" alwaysnotify="TRUE"/>
</interface>
<script type="text/brightscript" uri="pkg:/components/gridcontent.brs" />
</component>


'**** gridcontent.brs
Sub init()
m.top.functionName="setGridContent"
m.programmarkupgrid=m.global.findnode("programmarkupgrid") 'We're going to use this in SetGridContent() so we need to find it
End Sub

Function setGridContent()
Print "in setGridContent--"
m.array1=m.top.array1
m.array2=m.top.array2
m.array3=m.top.array3 'if m.array3 is an array then we need to reference by numerical index or associative index or for each unless we're just referencing the array as the entire object
gridx=1 'this variable isn't used or referenced
rows=0 'this variable isn't used or referenced
temp=[] 'creates an array called temp
m.programmarkupgrid.numColumns=m.array3
Print "NUMBER OF COLUMNS>>>>>>>>>>>>>>>>>>>>>>>>> "+(m.programmarkupgrid.numColumns.count()-1).ToStr()
For i=0 To (m.programmarkupgrid.numColumns.count()-1) 'this expects a numerical value for m.programmarkupgrid.numColumns so add a "count()-1"
temp[i]=312
Next
m.programmarkupgrid.columnwidths=temp 'This sets columnwidths to the newly populated array 'temp'
End Function





'Calling thread to initiate the task
Function prearray()
m.ContentTask_preslot=createObject("RoSGNode","GridContent")
m.ContentTask_preslot.array1=m.array1data 'this loads the gridcontent component's array1 field with the m.array1data conent
m.ContentTask_preslot.array2=m.array2data 'this loads the gridcontent component's array2 field with the m.array2data conent
m.ContentTask_preslot.array3=m.array3data 'this loads the gridcontent component's array3 field with the m.array3data conent
m.ContentTask_preslot.ObserveField("staus","pre_grid") 'this monitors for a change in the status field and then jumps to the pre_grid function in the current thread
m.ContentTask_preslot.control="RUN"
End Function

0 Kudos
btpoole
Channel Surfer

Re: rsgNode & Task

"destruk" wrote:
I don't think I understand what your concern is.
In your main scenegraph thread you can grab any node in the app by doing a m.mynodeineed=m.top.findnode("id name") provided it is specified in the xml markup as a required object to load - and then you can access it and modify anything it contains or displays or controls from that main scenegraph thread.
In the component threads you can grab any node from the main app by doing a m.mynodeineed=m.global.findnode("id name") - provided it has been loaded in the main thread (AFIK?) and then you can access it and modify anything it contains or displays or controls from that component thread.
In the component or task threads, if something is specified in its own xml, you would use m.top.findnode to grab it and utilize it.
The individual values of a node, once you have found it, can be edited anywhere.

Just how many items are you trying to parse or build here?

Would this code make any sense to you?
<?xml version="1.0" encoding="UTF-8"?>
<!-- ***** gridcontent.xml ***** -->
<component name="GridContent" extends="Task">

<interface>
<field id="array1" type="roArray" />
<field id="array2" type="roArray" />
<field id="array3" type="roArray" />
<!-- added status field which will notify observers every time the value changes -->
<field id="status" type="string" alwaysnotify="TRUE"/>
</interface>
<script type="text/brightscript" uri="pkg:/components/gridcontent.brs" />
</component>


'**** gridcontent.brs
Sub init()
m.top.functionName="setGridContent"
m.programmarkupgrid=m.global.findnode("programmarkupgrid") 'We're going to use this in SetGridContent() so we need to find it
End Sub

Function setGridContent()
Print "in setGridContent--"
m.array1=m.top.array1
m.array2=m.top.array2
m.array3=m.top.array3 'if m.array3 is an array then we need to reference by numerical index or associative index or for each unless we're just referencing the array as the entire object
gridx=1 'this variable isn't used or referenced
rows=0 'this variable isn't used or referenced
temp=[] 'creates an array called temp
m.programmarkupgrid.numColumns=m.array3
Print "NUMBER OF COLUMNS>>>>>>>>>>>>>>>>>>>>>>>>> "+(m.programmarkupgrid.numColumns.count()-1).ToStr()
For i=0 To (m.programmarkupgrid.numColumns.count()-1) 'this expects a numerical value for m.programmarkupgrid.numColumns so add a "count()-1"
temp[i]=312
Next
m.programmarkupgrid.columnwidths=temp 'This sets columnwidths to the newly populated array 'temp'
End Function





'Calling thread to initiate the task
Function prearray()
m.ContentTask_preslot=createObject("RoSGNode","GridContent")
m.ContentTask_preslot.array1=m.array1data 'this loads the gridcontent component's array1 field with the m.array1data conent
m.ContentTask_preslot.array2=m.array2data 'this loads the gridcontent component's array2 field with the m.array2data conent
m.ContentTask_preslot.array3=m.array3data 'this loads the gridcontent component's array3 field with the m.array3data conent
m.ContentTask_preslot.ObserveField("staus","pre_grid") 'this monitors for a change in the status field and then jumps to the pre_grid function in the current thread
m.ContentTask_preslot.control="RUN"
End Function



Makes perfect sense. I believe you answered my question in that making the node global or defining it in its own xml. Since the post I kept working around and was able to pass only the needed info to the task. All of my rsgnodes are defined in a single xml file, probably not great way to do it but until recently worked very well, they loaded when script initialized and were waiting on orders. I did think about making global but was just hoping that the rsgnode as a whole would be seen by the task. Thank you for taking the time to spell it out with examples. Part of the example code I posted was for a reference only and not the exact code and the majority of the function was left out (ie gridx=1 stuff)  because it didn't apply to my problem or was "clutter". .  Thanks again.
0 Kudos
destruk
Binge Watcher

Re: rsgNode & Task

No problem btpoole - I looked over the wiki pages again and it appears nodes created within a task node are unable to be exported outside the task node?  I'm not sure if I read that right.  I wasn't able to use interface fields of a task node's xml if they were objects 😞  This makes sense as they don't want some objects to be allowed outside a task node so it's easier to block every possible object than to have to look at what it is before deciding.
0 Kudos
RokuNB
Roku Guru

Re: rsgNode & Task

"btpoole" wrote:
Makes perfect sense. I believe you answered my question in that making the node global or defining it in its own xml. Since the post I kept working around and was able to pass only the needed info to the task. All of my rsgnodes are defined in a single xml file, probably not great way to do it but until recently worked very well, they loaded when script initialized and were waiting on orders. I did think about making global but was just hoping that the rsgnode as a whole would be seen by the task.

Ah? I did not get that - are you saying that you were defining multiple custom components in a single XML file and that was working (no error) - plus they were sharing data or scriprs somehow? I haven't seen that documented as supported and have no idea what the outcome might be - but do tell more - did it work before? Does it still work? How does it differ from doing 1-component-per-file?
0 Kudos
RokuNB
Roku Guru

Re: rsgNode & Task

"destruk" wrote:
I looked over the wiki pages again and it appears nodes created within a task node are unable to be exported outside the task node?  I'm not sure if I read that right.  I wasn't able to use interface fields of a task node's xml if they were objects 😞  This makes sense as they don't want some objects to be allowed outside a task node so it's easier to block every possible object than to have to look at what it is before deciding.

That shouldn't be the case - not sure, but does not sound right. Can you show minimal example and/or point to exact doco wording?
0 Kudos
destruk
Binge Watcher

Re: rsgNode & Task

From the docs --
Task Node Thread Fully-Owned Node Objects

Task node threads can create node and ContentNode node objects that are fully owned by the Task node thread. These node objects cannot be parented to unowned nodes, or be set as fields of unowned nodes. Entire trees of the nodes fully owned by the Task node thread may be created.
0 Kudos
btpoole
Channel Surfer

Re: rsgNode & Task

"RokuNB" wrote:
"btpoole" wrote:
Makes perfect sense. I believe you answered my question in that making the node global or defining it in its own xml. Since the post I kept working around and was able to pass only the needed info to the task. All of my rsgnodes are defined in a single xml file, probably not great way to do it but until recently worked very well, they loaded when script initialized and were waiting on orders. I did think about making global but was just hoping that the rsgnode as a whole would be seen by the task.

Ah? I did not get that - are you saying that you were defining multiple custom components in a single XML file and that was working (no error) - plus they were sharing data or scriprs somehow? I haven't seen that documented as supported and have no idea what the outcome might be - but do tell more - did it work before? Does it still work? How does it differ from doing 1-component-per-file?

Maybe I used wrong terminology. My single xml file is similar to this:
HomeScene.xml
<?xml version="1.0" encoding="utf-8" ?>
<!--********** Copyright 2016 Roku Corp.  All Rights Reserved. **********-->
<component name="HomeScene" extends="Scene" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">

<script type="text/brightscript" uri="pkg:/source/main.brs" />
<children>
<!--******************************************** -->
<!--INITIAL TOPLOGO AND BACK GROUND -->

  <Overhang
    title = ""
    showOptions = "true"
    height= "115"
    logoBaselineOffset="15"
    optionsAvailable = "true" />


    <Rectangle
            id="background"
            color="#000000"
            width="1280"
            height="720"
            translation="[0,97]"
             />
   <Poster
       id = "TopLogo"
       translation = "[10, 0 ]"
       width = "250"
       height = "97"
       uri= "pkg:/images/beta_overhang_logo.png"
       visible= "true">
    </Poster>
<!--******************************************** -->

<Label
  id = "instructLabel"
  text = "" />

  <Poster
      id="Background"
      width="1280"
      height="720"
      />
<!--************************************************  -->

<!--  -->
 <Label
 id = "ActivationDate"
 height = "50"
 width = "300"
 text = ""
 color="#f44242"
 font = "font:MediumBoldSystemFont"
 translation = "[300,20]"
 visible= "false"
  />

<!--************************************************  -->
<!--  ACTIVATION DIALOG-->
<Label
id = "Message"
height = "50"
width = "600"
wrap="true"
text = ""
numLines="2"
color="#f1f442"
font = "font:MediumBoldSystemFont"
translation = "[290,60]"
visible= "false"
 />
 <Label
   id = "theMessage"
   text = "" />

   <Poster
       id="MessageBackground"
       width="1280"
       height="720"
       />
<!--************************************************  -->
    <MarkupList
        id="ChannelList"
        itemComponentName="ChannelListItem"
        focusFootprintBitmapUri= "pkg:/images/channellist.9.png"
        itemSize="[65,70]"
        itemSpacing="[0, 5]"
        translation="[40,360]"
        numRows= "4"
        numColumns="1"
    />


  <MarkupGrid
      id= "TimeList"
    itemComponentName="TimeListItem"
      columnWidths="[300,300,300,300]"
      itemSize="[15,40]"
      rowHeights="[15, 20]"
    numColumns="4"
    numRows="1"
      itemSpacing="[0,50]"
    translation="[220,320]"
      />

    <MarkupGrid
      id= "ProgramGrid"
      itemComponentName="ProgramGridItem"
      focusBitmapUri= "pkg:/images/1focus_grid.9.png"
      numRows="4"
      itemSpacing="[4,6]"
      numColumns="1"
      translation= "[160, 350]"
      columnWidths="[312]"
      itemSize="[25,70]"
      fixedlayout="false"
      drawFocusFeedbackOnTop="false"
      />
</children>
</component>

There are more in there than shown.  After the first main.brs runs, the HomeScene is created using the Home.xml In the home.brs I am setting the rsgnodes
m.ProgramMarkupGrid = m.top.findNode("ProgramGrid")

and so on. My initial problem was making the m.ProgramMarkupGrid visible in a task. I knew I could pass the fields to the task, do whatever I needed to the value and return back a value on the other side to utilize. In this particular case I was setting column widths based on the result of the task. I was hoping to call the m.ProgramMarkupGrid directly from the task but I was unable to do so. To get it to work I passed only the fields needed. 
0 Kudos