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: 
matrixebiz
Roku Guru

Re: Close Channel

Are there code changes I need to do to the SceneGraph SDK so as to not have the channel locking up users device trying to exit the channel?  : https://github.com/rokudev/videoplayer-channel

Is there another SceneGraph template like this that is more up to date that i should be using to be ready for the future changes? Thanks
0 Kudos
belltown
Roku Guru

Re: Close Channel

"destruk" wrote:
So you can't just use "END" in the script section of a callback?  Does that leave processes running?

Here's a demo channel (HD). Set your screensaver timeout to one minute and see what happens.

Main() creates MainScene. Main() prints to the console every 3 seconds to show that it's running. After 100 seconds (long enough for screensaver activation), Main() closes the scene and exits.

Meanwhile, MainScene has a timer that runs every 15 seconds. The timer callback calls END, which does indeed exit the callback. However, it can be seen in the console output that the timer keeps firing every 15 seconds until screensaver activation.

MainScene has a Task that runs continuously printing to the console every 15 seconds.

The key point is that even though Main() exits, the Task and the screensaver keep running. The UI is unresponsive requiring a re-boot.

source/Main.brs

sub Main()
   screen = CreateObject("roSGScreen")
   scene = screen.createScene("MainScene")
   port = CreateObject("roMessagePort")
   screen.SetMessagePort(port)
   screen.Show()
   ts = CreateObject("roTimespan")
   while true
       msg = Wait(3000, port)
       print "Main() is running"
       if ts.TotalSeconds() > 100
           print "Closing the screen"
           screen.Close()
           exit while
       end if
       if Type(msg) = "roSGScreenEvent"
           print "roSGScreenEvent"
           if msg.IsScreenClosed()
               exit while
           end if
       end if
   end while
   print "** Main() terminating ***"
end sub

components/MainScene.xml

<?xml version="1.0" encoding="UTF-8"?>

<component name="MainScene" extends="Scene">
 <script type="text/brightscript">
   <![CDATA[

   sub init()
     m.top.findNode("label").font.size = 120
     m.timer = m.top.findNode("timer")
     m.timer.ObserveField("fire", "onFire")
     m.timer.control = "start"
   end sub

   sub onFire()
     print "***** Main Scene timer fired *****"
     END
     print "***** Should not get here *****"
   end sub

   ]]>
</script>
 <children>
   <Label
     id="label"
     width="1280"
     height="720"
     text="Hello, World!"
     font="font:LargeBoldSystemFont"
     horizAlign="center"
     vertAlign="center" />
   <TaskRunning />
   <Timer
     id="timer"
     repeat="true"
     duration="15" />
 </children>
</component>

components/TaskRunning.xml

<?xml version="1.0" encoding="UTF-8"?>

<component name="TaskRunning" extends="Task">
 <script type="text/brightscript">
   <![CDATA[

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

   function taskRun() as void
       port = CreateObject("roMessagePort")
       while true
           Wait(5000, port)
           print "Task is running"
       end while
   end function

   ]]>
 </script>
</component>

components/Screensaver.xml

<?xml version="1.0" encoding="UTF-8"?>

<component name="Screensaver" extends="Scene">
 <script type="text/brightscript">
   <![CDATA[

   sub init()
     m.top.findNode("seq").control = "start"
   end sub

   ]]>
 </script>
 <children>
   <Group>
     <Poster
       id="poster"
       uri="https://c1.staticflickr.com/9/8505/8418942879_d6f9e365b8_z.jpg"
       translation="[370, 120]"
       width="500"
       height="500" />
     <SequentialAnimation
       id="seq"
       repeat="true">
       <Animation
         duration="8"
         easeFunction="outCubic">
         <FloatFieldInterpolator
           key="[0,1]"
           keyValue="[1,0]"
           fieldToInterp="poster.opacity" />
       </Animation>
       <Animation
         duration="8"
         easeFunction="inCubic">
         <FloatFieldInterpolator
           key="[0,1]"
           keyValue="[0,1]"
           fieldToInterp="poster.opacity" />
       </Animation>
     </SequentialAnimation>
   </Group>
 </children>
</component>

source/RunScreenSaver.brs

sub RunScreenSaver()
   screen = CreateObject("roSGScreen")
   port = CreateObject("roMessagePort")
   screen.SetMessagePort(port)
   scene = screen.CreateScene("Screensaver")
   screen.Show()
   while true
       msg = Wait(0, port)
       if Type(msg) = "roSGScreenEvent"
           if msg.IsScreenClosed()
               exit while
           end if
       end if
   end while
end sub
0 Kudos
destruk
Streaming Star

Re: Close Channel

argh... 😞  Thanks Belltown
0 Kudos
EnTerr
Roku Guru

Re: Close Channel

"belltown" wrote:
"destruk" wrote:
So you can't just use "END" in the script section of a callback?  Does that leave processes running?

Putting END in a script callback function just exits the callback. It doesn't stop anything running, even the Scene it's running in - unless I misunderstand what you're saying.

Good grief - END does not exit the program?
Out of curiosity - what does STOP cause in such situation?
0 Kudos
belltown
Roku Guru

Re: Close Channel

"EnTerr" wrote:
"belltown" wrote:
"destruk" wrote:
So you can't just use "END" in the script section of a callback?  Does that leave processes running?

Putting END in a script callback function just exits the callback. It doesn't stop anything running, even the Scene it's running in - unless I misunderstand what you're saying.

Good grief - END does not exit the program?
Out of curiosity - what does STOP cause in such situation?

It appears that STOP behaves the same as END, the only difference being that when side-loaded, the channel will break into the debugger for a STOP. When run from a channel-store channel, STOP and END seem to behave the same way. I have a Timer in the main Scene that displays a message then calls END or STOP. The code after END/STOP does not execute, but the Scene and Timer remain active, and the message display continues updating whenever the timer fires. If I exit from Main() while the screensaver is active, the screensaver continues running, but the Roku does not respond to remote commands and has to be re-booted.
0 Kudos
EnTerr
Roku Guru

Re: Close Channel

"belltown" wrote:
It appears that STOP behaves the same as END, the only difference being that when side-loaded, the channel will break into the debugger for a STOP. When run from a channel-store channel, STOP and END seem to behave the same way. I have a Timer in the main Scene that displays a message then calls END or STOP. The code after END/STOP does not execute, but the Scene and Timer remain active, and the message display continues updating whenever the timer fires.

seems like a bug to me - but i can easily imagine someone dismissing it "works as designed, won't fix"

If I exit from Main() while the screensaver is active, the screensaver continues running, but the Roku does not respond to remote commands and has to be re-booted.

clearly a bug!
whose screensaver btw? channel's own or the system one
0 Kudos
btpoole
Channel Surfer

Re: Close Channel

Not meaning to hijack my own thread but I have another situation somewhat in the same lines as my original. The app starts in the main.brs and creates a scene (spinner) as the spinner is running,  the app continues to the next function which starts configuration stuff. If a particular situation is present,  a scene is created that creates a dialog box displaying to the users. Once the user is done reading the box, he/she can press the back or options button to close the dialog and continue into the app or home.brs (thru a task). All this works except that in order to continue into the home.brs, the user has to press the button twice (not intended). The first press closes the dialog box and leaves a gray screen. The second press enters the home.brs. I am under the impression that when the first button click occurs, the dialog would close and the original spinner would be visible as home.brs starts. Apparently the spinner is being closed or most likely I am not doing something right.  I am posting min code with hopes somebody could point out the flaw.
Sub RunUserInterface()
Print "RUNUSERINTERFACE"
OpeningDialog()
End Sub
''*************************************************************'
Function OpeningDialog()
?"In OpeningDialog"
screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
screen.setMessagePort(m.port)
scene = screen.CreateScene("OpeningDialog")
screen.show()
ConfigureStuff()

while(true)
  msg = wait(0, m.port)
  msgType = type(msg)

  if msgType = "roSGScreenEvent"

    if msg.isScreenClosed() then return ""
  end if
end while
end function
'*********************************************************
function configurestuff()
code stuff
Condition Exist so creae "WarnUser"

screen = CreateObject("roSGScreen")
port = CreateObject("roMessagePort")
screen.setMessagePort(port)
scene = screen.CreateScene("WarnUser")
screen.show()
    while (true)
     msg = wait(0, port)
      msgType = type(msg)
      ?msgType
       if msgType = "roSGScreenEvent"
          if msg.isScreenClosed()
      EXIT WHILE
    end if
    end if
end while
end function
'*****************************************************


<component name = "Warnuser" extends = "Scene" >
  <interface>
    <field id="Content" type="node"  />
    </interface>
  <script type="text/brightscript" uri="pkg:/source/main.brs" />

  <script type = "text/brightscript" >
  <![CDATA[
    sub init()
    dialogWarn()
    end sub


    sub dialogWarn()
      m.background  = m.top.findNode("Background")
      example = m.top.findNode("instructLabel")
      examplerect = example.boundingRect()
      centerx = (1280 - examplerect.width) / 2
      centery = (720 - examplerect.height) / 2
      example.translation = [ centerx, centery ]
      m.top.setFocus(true)
      di = CreateObject ("roDeviceInfo")
      serial=di.GetDeviceUniqueId()
      dialog = createObject("roSGNode", "Dialog")
      dialog.title = "  Channel Not Activated"
      dialog.optionsDialog = true
      dialog.message = "Danger Will Robinson"
      m.top.dialog = dialog
    end sub

    function onKeyEvent(key as String, press as Boolean) as Boolean
          if press then
            if key = "options"
            m.hometaskRegistryNode = m.top.findNode("hometaskRegistry")
            m.hometaskRegistryNode.control="RUN"
              return true
            end if
          end if

          return false
        end function

    ]]>







0 Kudos
belltown
Roku Guru

Re: Close Channel

"EnTerr" wrote:
"belltown" wrote:
It appears that STOP behaves the same as END, the only difference being that when side-loaded, the channel will break into the debugger for a STOP. When run from a channel-store channel, STOP and END seem to behave the same way. I have a Timer in the main Scene that displays a message then calls END or STOP. The code after END/STOP does not execute, but the Scene and Timer remain active, and the message display continues updating whenever the timer fires.

seems like a bug to me - but i can easily imagine someone dismissing it "works as designed, won't fix"

If I exit from Main() while the screensaver is active, the screensaver continues running, but the Roku does not respond to remote commands and has to be re-booted.

clearly a bug!
whose screensaver btw? channel's own or the system one

It's the channel's own, private screensaver, the same one I used in the demo code a few posts back.
0 Kudos
belltown
Roku Guru

Re: Close Channel

"btpoole" wrote:
most likely I am not doing something right


A couple of quotes from the documentation:


Important

There must be only one Scene Graph component extended from a scene node class in the pkg:/components directory.



While it is technically possible to have more than one scene per channel, we recommend you only have one roSGScreen and one Scene node. Child nodes of the scene can be treated as different "scenes" where you can then implement transitions between them.

If you fully grasp this principle, it will make things much easier going forward. In the old SDK, there was a concept of a "screen stack" where you could keep creating screens anywhere and everywhere as much as you liked. Each screen would stack on top of its parent, and when you closed it you'd be back in the parent screen right where you were before you created the child. This is how you're trying to use Scene Graph. However, SG is a totally different paradigm. You need to think in terms of the whole application being one super-Scene, a single Scene that contains all the components that make up the whole UI. You can show and hide components to give the appearance of multiple "screens", but they really all fall under the same Scene. A good way to familiarize yourself with this concept would be to run through a number of the Roku sample channels; the ones in https://github.com/rokudev tend to be a bit more representative of real-world situations than the ones in the Scene Graph XML Tutorial.
0 Kudos
btpoole
Channel Surfer

Re: Close Channel

"belltown" wrote:
"btpoole" wrote:
most likely I am not doing something right


A couple of quotes from the documentation:


Important

There must be only one Scene Graph component extended from a scene node class in the pkg:/components directory.



While it is technically possible to have more than one scene per channel, we recommend you only have one roSGScreen and one Scene node. Child nodes of the scene can be treated as different "scenes" where you can then implement transitions between them.

If you fully grasp this principle, it will make things much easier going forward. In the old SDK, there was a concept of a "screen stack" where you could keep creating screens anywhere and everywhere as much as you liked. Each screen would stack on top of its parent, and when you closed it you'd be back in the parent screen right where you were before you created the child. This is how you're trying to use Scene Graph. However, SG is a totally different paradigm. You need to think in terms of the whole application being one super-Scene, a single Scene that contains all the components that make up the whole UI. You can show and hide components to give the appearance of multiple "screens", but they really all fall under the same Scene. A good way to familiarize yourself with this concept would be to run through a number of the Roku sample channels; the ones in https://github.com/rokudev tend to be a bit more representative of real-world situations than the ones in the Scene Graph XML Tutorial.

bellotwn, thank you for the explanation.  If I understand correctly, there should be one main scene (my Home scene) in this case which is called from the main.brs. Once the Home is created all components of the app would be created , waiting in the wings to be shown. I think I understand. now just moving things around to do this might be tricky. Thanks again.
0 Kudos
Need Assistance?
Welcome to the Roku Community! Feel free to search our Community for answers or post your question to get help.

Become a Roku Streaming Expert!

Share your expertise, help fellow streamers, and unlock exclusive rewards as part of the Roku Community. Learn more.