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: 
renojim
Community Streaming Expert

Re: EnableBackButton does not work unless AddButton is used

You're basically giving the user 10ms to press the back button. You need to use an roTimespan object and check every 10ms if 10 seconds have passed. Each time through the loop you have to do a part/i] of the stuff that takes a while. If your stuff can't be broken up, then you don't have much choice but to do it all and put up a "please wait" message. I'll leave the details to the interested reader.

-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
roquoonewbie
Visitor

Re: EnableBackButton does not work unless AddButton is used

So you are saying there is no way at all in a Roku channel to present a "Please wait" message which gives the user an option of canceling the operation they are currently waiting for?

The operation could be as simple as one HTTP request which may take a long time (if the network is slow, for instance). It's the equivalent of canceling a browser navigation to a new page after it takes longer than the user would like to wait.

It seems hard to believe that Roku devs did not provide some way to listen for a user-driven event and completely (and instantly) close out of a screen when that event arrives.
0 Kudos
TheEndless
Channel Surfer

Re: EnableBackButton does not work unless AddButton is used

I don't think that's what he's saying at all. You just have to get a little creative. This is how I'd do it...

WARNING: psuedo-code

' Create message port that everything will use
messagePort = CreateObject("roMessagePort")

' Create url transfer for first URL
download1 = CreateObject("roUrlTransfer")
download1.SetPort(messagePort)
download1.SetUrl(url1)

Create url transfer for second URL
download2 = CreateObject("roUrlTransfer")
download2.SetPort(messagePort)
download2.SetUrl(url2)

' Create and show wait dialog
waitDialog = CreateObject("roMessageDialog")
waitDialog.SetMessagePort(messagePort)
' Add your waitDialog button(s)
' Show waitDialog
waitDialog.Show()

' Start downloads
download1.AsyncGetToString()
download2.AsyncGetToString()

' Listen for message
While True
msg = wait(10, messagePort)
If msg <> invalid Then
If Type(msg) = "roUrlEvent" Then
' Got a URL event, figure out which download it's for and process it
If msg.GetSourceIdentity() = download1.GetIdentity() Then
download1Result = msg.GetString()
' Do download1 processing
Else If msg.GetSourceIdentity() = download2.GetIdentity() Then
download2Result = msg.GetString()
' Do download2 processing
End If
Else If Type(msg) = "roMessageDialogEvent") Then
' Got a message dialog event, probably cancel
If msg.IsButtonPressed() Then
If msg.GetIndex() = cancelButton Then
' Kill the active downloads, and close the wait dialog
download1.AsyncCancel()
download2.AsyncCancel()
waitDialog.Close()
Exit While
End If
End If
End If
End If
End While
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
roquoonewbie
Visitor

Re: EnableBackButton does not work unless AddButton is used

Thank you both very much. I was able to use your proposed method such that I can now give the user the ability to cancel the async HTTP request by pressing back or clicking on a dialog "cancel" button (thought it is still a mystery why the back button will not fire an event unless there is also a dialog button).

However, as best as I can tell, your proposed method will only work for Async HTTP calls, correct?

In other words, if I have a function that "does a lot of stuff" which takes a while (but not necessarily makes HTTP calls), is there a way to set it up to run asyncronously (like the built in AsyncGetToString() method), so that I can cancel it via something similar to the HTTP AsyncCancel() ?

Is it possible to define our own Async functions? Or are we relegated to the few Async functions that are provided by the Roku API?
0 Kudos
RokuJoel
Binge Watcher

Re: EnableBackButton does not work unless AddButton is used

"roquoonewbie" wrote:

In other words, if I have a function that "does a lot of stuff" which takes a while (but not necessarily makes HTTP calls), is there a way to set it up to run asyncronously (like the built in AsyncGetToString() method), so that I can cancel it via something similar to the HTTP AsyncCancel() ?

Is it possible to define our own Async functions? Or are we relegated to the few Async functions that are provided by the Roku API?

Brightscript is not multi-threaded at the moment, except in a few instances where there are Async functions, which allow you to initiate an action, and then perform other actions while waiting for that first action to complete. You are not able to define your own Async functions at the present time.

- Joel
0 Kudos
roquoonewbie
Visitor

Re: EnableBackButton does not work unless AddButton is used

Thank you for the information, Joel. So, just to confirm my understanding 100%, is there currently no way at all in Brightscript to present a "waiting" dialog message to users while waiting for time-intensive logic to complete, and give the user an option to cancel (or go back) such that the logic which was running is cancelled/aborted? No way at all?

Also, can you comment on why the EnableBackButton property does not work unless AddButton is also used? Is that intended or is it a bug?
0 Kudos
RokuJoel
Binge Watcher

Re: EnableBackButton does not work unless AddButton is used

I haven't tested that myself, but if it is behaving as described, it might be considered a bug.

There is no reason why, within any logic I can imagine, you cannot simply check a message port every so often to see if a button has been pressed, and if you are using multiple functions within your logic, then pass the port and dialog box variables from function to function so that it is available in each function. Then if a button has been pressed, you return from wherever you are to the calling function. You may need to use a return value to notify the calling functions that you are aborting your logic.

You could also use global variables to make your dialog and port available everywhere, instead of the more tedious parameter passing.

- Joel
0 Kudos
roquoonewbie
Visitor

Re: EnableBackButton does not work unless AddButton is used

I thought Brightscript did not support global variables?

From the Brightscript reference manual:

"BrightScript does not support global variables. Except, there is one hard-coded global variable "global" that is an interface to the global BrightScript Component. The global component contains all global library functions."

Also, how exactly do you check a message port for the last message? Is a "wait()" required? In other words, would this simply return the last message which the port received, or is there a better way?

dlgMsg = wait(1, port)
0 Kudos
RokuJoel
Binge Watcher

Re: EnableBackButton does not work unless AddButton is used

you would use the m variable to create your port and dialog:

m.port=createobject("romessageport")
m.dialog=CreateObject("roMessageDialog")

"roquoonewbie" wrote:

Also, how exactly do you check a message port for the last message? Is a "wait()" required? In other words, would this simply return the last message which the port received, or is there a better way?

There is a way to do it without using wait:

msg = port.GetMessage()
if type(msg) = "roUniversalControlEvent" then
<act on message>
end if


but wait is a pretty simple way to go. I would use the above method for a game that has high performance demands on your device, otherwise, msg=wait(25,port) would be my suggestion.

- Joel
0 Kudos
roquoonewbie
Visitor

Re: EnableBackButton does not work unless AddButton is used

Thanks to all of you. Passing the handle to the dialog port down into the time intensive function, and querying the last message posted to it on each loop inside that function worked perfectly.

All it took was this:


msg = dialogport.GetMessage()
if type(msg) = "roMessageDialogEvent" then
if msg.IsButtonPressed() or msg.isScreenClosed() then
return 3
end if
end if



The simplest solutions are always the best ones. I had no idea you could poll the port for it's latest message (as opposed to listening to events from it).

Thanks again!
0 Kudos