dan_shneider
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
06:52 AM
More server requests on task element
Hey,
I do some server requests in a task. eventually I get the final response with the videos I need to display. that's fine. I send a callback to the VideoGridScene.
Now, I need to request something again from the server. let's say, when the video pauses.
My task has a property with the Video node, and I get the 'pause' event.
But, on that point, I cannot access the registry to get some values nor can I request
Errors:
'Dot' Operator attempted with invalid BrightScript Component or interface reference. (runtime error &hec)
and
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)
What am I doing wrong?
I do some server requests in a task. eventually I get the final response with the videos I need to display. that's fine. I send a callback to the VideoGridScene.
Now, I need to request something again from the server. let's say, when the video pauses.
My task has a property with the Video node, and I get the 'pause' event.
But, on that point, I cannot access the registry to get some values nor can I request
Errors:
'Dot' Operator attempted with invalid BrightScript Component or interface reference. (runtime error &hec)
and
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)
What am I doing wrong?
14 REPLIES 14
EnTerr
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
11:18 AM
Re: More server requests on task element
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
See also https://sdkdocs.roku.com/display/sdkdoc ... pt+Support
dan_shneider
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
12:28 PM
Re: More server requests on task element
"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
Not sure I understood (I did understand the Haram part 🙂
Anyhow, I guess what I am saying is that I need a task node that can act as a continuous server.
Task.xml is just a sample. that's not the real name of the node of course. my function within the task sends the result to the observer gets it and all is good.[/font][/color]
My question was actually about next step: I need to send more requests according to the player event (star, stop, pause and so on...).[/font][/color]
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
01:15 PM
Re: More server requests on task element
Do you have any code showing how you're trying to do this?
dan_shneider
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
01:35 PM
Re: More server requests on task element
"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
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
02:13 PM
Re: More server requests on task element
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.
EnTerr
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
05:03 PM
Re: More server requests on task element
How do we explain the bizarre "colonics"?
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?
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?
dan_shneider
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
10:10 PM
Re: More server requests on task element
"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?
Yes, #378 is CreateObject("roUrlTransfer")
dan_shneider
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-08-2017
11:33 PM
Re: More server requests on task element
"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.
Not so sure I understood what should I do in the Scene level & in the task level. any code snippet?
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-09-2017
01:03 AM
Re: More server requests on task element
Here's a very simplified example that illustrates the concept. Note that I don't include the Video node as a field in the Task node as you've done. That just seems weird to me. It makes more sense to keep the Video node contained within the Render thread and communicate any state changes that the Task needs to know about via an interface field on the Task node that only contains the information the Task needs to know (i.e. the video state in this case). The Task just prints out any changes to the Video state by observing its interface field. You can add your own code to use your roUrlTransfer object to send that data where it needs to go.
Test.xml:
Test.brs:
TaskServer.xml:
TaskServer.brs:
Test.xml:
<?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>
Test.brs:
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
TaskServer.xml:
<?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>
TaskServer.brs:
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