I make one sample App for Roku. It is as below.
MainScene.brs
sub init() m.TaskNodeThread = CreateObject("roSGNode", "TaskNodeThread") m.TaskNodeThread.control = "RUN" end sub
MainScene.xml
<?xml version="1.0" encoding="UTF-8"?> <component name="MainScene" extends="Scene" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd"> <script type="text/brightscript" uri="pkg:/components/MainScene.brs" /> </component>
TaskNodeThread.brs
sub init() m.TestContent = testContentFunction(testData) end sub
function testContentFunction(testData as String) as String
'Here I need some calculation and It takes a lot of time.
'It takes around 50 to 60 Sec and I got this error in this function.
'I know Rendered thread timeout limit is 10 Sec that's why I have written this
function in Task Node.
'Even so, it waits only for 10 Sec.
'Can anyone suggest where should I write this type of logic in Roku which is not
affected by UI.
end function
TaskNodeThread.xml
<?xml version="1.0" encoding="UTF-8"?> <component name="TaskNodeThread" extends="Task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd"> <script type="text/brightscript" uri="pkg:/components/TaskNodeThread.brs" /> </component>
Review the documentation on correctly setting up a task
https://developer.roku.com/docs/references/scenegraph/control-nodes/task.md
the way you have set this up 'testContentFunction(testData)' will run when created
MainScene.brs set testdata for task here before "run"
sub init() m.TaskNodeThread = CreateObject("roSGNode", "TaskNodeThread")
m.TaskNodeThread.TestContent=testData
m.TaskNodeThread.observefield("resultContent","onResultContentChanged") 'observe field to see if we are done with task
m.TaskNodeThread.control = "RUN"
end sub
sub onResultContentChanged(event) 'called when task completes
data=event.getdata()
'do stuff with data here
end sub
TaskNodeThread.xml needs and interface for test content
<?xml version="1.0" encoding="UTF-8"?> <component name="TaskNodeThread" extends="Task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">
<interface>
<field id = "resultcontent" type = "node" /> <field id = "testcontent" type = "node" /> </interface>
<script type="text/brightscript" uri="pkg:/components/TaskNodeThread.brs" /> </component>
TaskNodeThread.brs m.top.functionName is what is called when .control="run" is set
sub init()
m.top.functionName = "testContentFunction" end sub
function testContentFunction() as String
testdata=m.top.testcontent
'do stuff here
m.top.resultContent = resultOfStuffDone 'signal task has completed
end function
Review the documentation on correctly setting up a task
https://developer.roku.com/docs/references/scenegraph/control-nodes/task.md
the way you have set this up 'testContentFunction(testData)' will run when created
MainScene.brs set testdata for task here before "run"
sub init() m.TaskNodeThread = CreateObject("roSGNode", "TaskNodeThread")
m.TaskNodeThread.TestContent=testData
m.TaskNodeThread.observefield("resultContent","onResultContentChanged") 'observe field to see if we are done with task
m.TaskNodeThread.control = "RUN"
end sub
sub onResultContentChanged(event) 'called when task completes
data=event.getdata()
'do stuff with data here
end sub
TaskNodeThread.xml needs and interface for test content
<?xml version="1.0" encoding="UTF-8"?> <component name="TaskNodeThread" extends="Task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">
<interface>
<field id = "resultcontent" type = "node" /> <field id = "testcontent" type = "node" /> </interface>
<script type="text/brightscript" uri="pkg:/components/TaskNodeThread.brs" /> </component>
TaskNodeThread.brs m.top.functionName is what is called when .control="run" is set
sub init()
m.top.functionName = "testContentFunction" end sub
function testContentFunction() as String
testdata=m.top.testcontent
'do stuff here
m.top.resultContent = resultOfStuffDone 'signal task has completed
end function
Thank you so much for your response. That's what I was looking for.
I read this documentation for stopping the Task node. Is there any way or field available for the Stopping the Task Thread between the Logic?
like
m.TaskNodeThread.control = "STOP"
And
I take the type array in the field and use it like below. But it gives this error => Interface is not a member of BrightScript Component (runtime error &hf3). Is it the correct way I used it?
TaskNodeThread.xml
<field id = "resultcontent" type = "node" />
TaskNodeThread.brs
function testContentFunction() as String testdata=m.top.testcontent 'do stuff here for val = 0 to Value - 1 m.top.resultContent.Push(Value[val]) end for return "" end function
The single value, I am able to fetch using event. But, I need to fill this whole value in an array.
Using Global value I am able to do
But, only assocaaray available in Global Node.
So, I need to convert array to assocarray in Task Thread and Render thread I again convert to assocarray to array and used. This is right approch or you suggest me to any better approch?
The single value, I am able to fetch using event. But, I need to fill this whole value in an array.
Using Global value I am able to do
But, only assocaaray available in Global Node. So I convert to array to assocarray in Task Thread and Render thread I again convert to assocarray to array and used. This is right approch or you suggest me to any better approch.
m.global.addfield("resultContentResponse","assocarray", TRUE)
TaskNodeThread
contentArr = CreateObject("roArray",Value.Count(),false) for val = 0 to Value - 1
contentArr.Push(Value[val])
end for assocArrayContent = formatJSON(contentArr) m.Global.resultContentResponse = assocArrayContent
MainScene
response = ParseJson(m.Global.resultContentResponse) 'do stuff here
For Each res In response
Print "My Response here: " + res
End For
Sure... you should be able to m.TaskNodeThread.control = "STOP" at some point in your mainscene after the task has been started.
if you need to return an array change the type to array. same with test content if you want to pass as a different type such as "string".
<field id = "resultcontent" type = "array" />
<field id = "testcontent" type = "string" />
if you do this like below, then it will trigger the onResultContentChanged() in the mainscene each time you push to the array since this is what is being observed.
for val = 0 to Value - 1 m.top.resultContent.Push(Value[val]) end for
Do something like this instead
resultContent=[]
for val = 0 to Value.count() - 1 resultContent.Push(Value[val]) end for
m.top.resultContent.append(resultContent) 'only trigger once you are done
I don't think you want to store this in the GlobalAA node to pass the data
from mainscene you can access the result
response = m.TaskNodeThread.resultContent
Thank you so much for sharing this information!...