"EnTerr" wrote:
Hard to read your tea leafs but seems as if you are trying to use some components that are "haram" 🙂 in RSG (render thread, specifically). Seeing that "Task.xml" is mentioned, you are probably doing it before spawning a task thread.
See also https://sdkdocs.roku.com/display/sdkdoc ... pt+Support
"belltown" wrote:
Do you have any code showing how you're trying to do this?
Sure. this is how I init the Task:m.babatorTask = createObject("RoSGNode", "BabatorTask")
m.babatorTask.observeField("babator_recommendations", "OnRecommendationsFetched")
m.babatorTask.babator_api_key = "API_KEY"
m.babatorTask.video_player = m.VideoGrid.liveVideo.Video
m.babatorTask.control = "RUN"
And this is the task code (part of it):<?xml version = "1.0" encoding = "utf-8" ?>
<!--********** B A B A T O R **********-->
<component name = "BabatorTask" extends = "Task" >
<interface>
<field id = "babator_api_url" type = "string" />
<field id = "babator_api_key" type = "string" />
<field id = "babator_recommendations" type = "string" />
<field id = "video_player" type="node"/>
</interface>
<script type = "text/brightscript" >
<![CDATA[
sub init()
m.top.functionName = "startBabator"
end sub
function startBabator()
userRequest = CreateObject("roUrlTransfer")
port = CreateObject("roMessagePort")
userRequest.SetMessagePort(port)
userRequest.SetUrl(url)
userRequest.AddHeader("x-api-key",m.top.babator_api_key)
userRequest.AddHeader("x-is-native","true")
if (userRequest.AsyncGetToString())
while (true)
msg = wait(0, port)
if (type(msg) = "roUrlEvent")
code = msg.GetResponseCode()
print "user response code: " + code.ToStr()
if (code = 200) 'response OK
m.top.babator_recommendations = msg.GetString()
else
print "ERROR in user request: " + userRequest.GetFailureReason()
endif
else if (event = invalid) 'response is invalid
print "invalid !!!"
userRequest.AsyncCancel()
endif
exit while
end while
endif
return invalid
end function
BRIGHTSCRIPT: ERROR: roUrlTransfer: class PLUGIN|MARKUP on thread RENDER: pkg:/components/Task.xml(378)
BRIGHTSCRIPT: ERROR: roMessagePort: Trying to construct a message port on a non-plugin thread: pkg:/components/Task.xml(379)
"EnTerr" wrote:
How do we explain the bizarre "colonics"?BRIGHTSCRIPT: ERROR: roUrlTransfer: class PLUGIN|MARKUP on thread RENDER: pkg:/components/Task.xml(378)
BRIGHTSCRIPT: ERROR: roMessagePort: Trying to construct a message port on a non-plugin thread: pkg:/components/Task.xml(379)
Seems awfully peculiar - could this be caused by assigning a Video node to a Task field?
Not something i would have tried but it shouldn't bind the task spawned to the render thread, right?
PS. Why is the diagnostic text so weird? Is it trying to say that PLUGIN and MARKUP are mutually exclusive flags? I am guessing #378 is `userRequest = CreateObject("roUrlTransfer")`? Why is this the RENDER thread if it's in the Task runner function?
"belltown" wrote:
To use a Task as a continuous server, use the port form of ObserveField(), specifying an roMessagePort used to wait for changes on each item that you wish to observe. You can use the same port you use for your roUrlTransfer object. In the Task thread code, define a message loop that calls Wait() on the port. If an observed field changes, an roSGNodeEvent message is received. Call GetField() and GetData() on this message to get the name of the field that changed and its value. You only need to set the Task's control field to "RUN" one time, to start it up. Thereafter, it will handle observed field changes each time they occur in its main Wait loop.
<?xml version="1.0" encoding="UTF-8"?>
<component name="Test" extends="Scene">
<script type="text/brightscript" uri="pkg:/components/Test.brs" />
<children>
<Video id="videoNode">
<ContentNode role="content"
url="https://archive.org/download/Plan9FromOuterSpace1958/Plan-9-from-Outer-Space.mp4"
title="Test Video" />
</Video>
<TaskServer id="taskServerNode" />
</children>
</component>
sub init()
m.taskServerNode = m.top.findNode("taskServerNode")
m.taskServerNode.ObserveField("stateOutput", "onTaskStateOutput")
m.videoNode = m.top.findNode("videoNode")
m.videoNode.SetFocus(true)
m.videoNode.ObserveField("state", "onVideoState")
m.videoNode.control = "play"
end sub
sub onVideoState()
m.taskServerNode.stateInput = m.videoNode.state
end sub
sub onTaskStateOutput()
print "Task state: "; m.taskServerNode.stateOutput
end sub
function onKeyEvent(key as string, press as boolean) as boolean
handled = false
if press
if key = "play"
if m.videoNode.state = "playing"
m.videoNode.control = "pause"
else if m.videoNode.state = "paused"
m.videoNode.control = "resume"
else if m.videoNode.state = "stopped"
m.videoNode.control = "play"
end if
handled = true
end if
end if
return handled
end function
<?xml version="1.0" encoding="UTF-8"?>
<component name="TaskServer" extends="Task">
<script type="text/brightscript" uri="pkg:/components/TaskServer.brs" />
<interface>
<field id="stateInput" type="string" alwaysNotify="true" />
<field id="stateOutput" type="string" alwaysNotify="true" />
</interface>
</component>
sub init()
m.top.functionName = "taskRun"
m.top.control = "RUN"
end sub
function taskRun() as void
port = CreateObject("roMessagePort")
m.top.ObserveField("stateInput", port)
while true
msg = Wait(0, port)
if Type(msg) = "roSGNodeEvent"
field = msg.GetField()
state = msg.GetData()
if field = "stateInput"
print "stateInput: "; state
m.top.stateOutput = state
end if
end if
end while
end function