Stuck with roScreen

I’m trying to get a handle on how roScreen works, and I’m missing something. In the code below, I show a red screen. When the user taps the OK button, I show a green screen. When the user taps OK again, I’d expect to go back and see a red screen, but that doesn’t happen. It is getting to the code, but the green screen is not cleared.

Any help would be appreciated!


Function showRedScreen()     
    port = CreateObject("roMessagePort")
    screen = CreateObject("roScreen", true)
    screen.Clear(&hFF0000FF)
    screen.SwapBuffers()
   
    screen.SetMessagePort(port)
   
    while true
        msg = wait(0, port)
        print "Red screen message"
        if type(msg) = "roUniversalControlEvent" then
            if msg.GetInt() = 6
                showGreenScreen()                
                screen.Clear(&hFF0000FF)
                screen.SwapBuffers()
            endif
        endif
    end while
End Function

Function showGreenScreen()     
    port = CreateObject("roMessagePort")
    screen = CreateObject("roScreen")
    screen.Clear(&h00FF00FF)
    screen.SetAlphaEnable(true)
   
    screen.SwapBuffers()
    screen.SetMessagePort(port)
    
    while true
         msg = wait(0, port)
        print "Green screen message"
         if type(msg) = "roUniversalControlEvent" then
             if msg.GetInt() = 6
                screen = invalid
                return true
             endif
         endif
     end while
End Function

Where is your sub main() ?

Also, your showGreenScreen should be something like:

Function showGreenScreen(screen as object) 
    port = screen.getmessageport()
    screen.Clear(&h00FF00FF) 
    screen.SwapBuffers()
    while true
         msg = wait(0, port)
        print "Green screen message"
         if type(msg) = "roUniversalControlEvent" then
             if msg.GetInt() = 6
                screen = invalid
                return true
             endif
         endif
     end while
End Function

and called with ShowGreenScreen(screen)

Not sure why you would want to launch a separate instance of roScreen.

  • Joel

“RokuJoel” wrote:
Where is your sub main() ?

Also, your showGreenScreen should be something like:

Function showGreenScreen(screen as object) 
    port = screen.getmessageport()
    screen.Clear(&h00FF00FF) 
    screen.SwapBuffers()
    while true
         msg = wait(0, port)
        print "Green screen message"
         if type(msg) = "roUniversalControlEvent" then
             if msg.GetInt() = 6
                screen = invalid
                return true
             endif
         endif
     end while
End Function

and called with ShowGreenScreen(screen)

Not sure why you would want to launch a separate instance of roScreen.

  • Joel

I left main out, but it just calls ShowRedScreen.

I don’t want greenscreen and redscreen to use the same screen. I want greenscreen to push a new screen on the stack and then pop it off when complete.

However, I just found the issue. It’s that the wait is blocking and the redscreen wasn’t getting cleared as expected. Changing the wait(0) to wait(1) resolved the issue.

I should add that I want to launch a separate instance of roScreen because I’m considering building a screen library that allows me to build apps that are more like Hulu+ than the standard ro components. Creating new instances simplifies the object model considerably.

This code is just a prototype to help me test the possibilities. So my red screen object would look something like this:


Function CreateRedScreen() as Object
    obj = CreateScreenCore()
        
    obj.draw = Function() 
        m.screen.Clear(&hFFFF00FF)
        m.screen.SwapBuffers()
    End Function
    
    obj.display = function() 
        m.Draw() 
        msg = wait(1, m.port)
        if type(msg) = "roUniversalControlEvent" then
            if msg.GetInt() = 5
                print "Red screen value is ", m.value
                m.value = m.value + 1
            endif
        endif
        return CreateScreenEvent(m.screen, msg)
    end function
 
    obj.screen.SetMessagePort(obj.port)
    
    return obj 
End Function

And you can see then, how that can be extended. The caller of “red screen” would be something like:


Function showNewRedScreen() 
    redScreen = CreateRedScreen()
    
    while true
        event = redScreen.display()
        if type(event.msg) = "roUniversalControlEvent" then
            if event.msg.GetInt() = 6
                ShowGreenScreen()
            endif
        endif
    end while
End Function

Now, RedScreen can handle it’s own events, and pass back both events of it’s own as well as events that it otherwise ignores.

RoScreens are pretty expensive objects. Each one contains a pair of full screen frame buffers (if double buffered). It would probably be better if your library accepted an existing RoScreen as an input parameter and just drew to it, so you don’t create unnecessary frame buffers. That’s how I usually structure my reusable RoScreen components.

–Mark

I’m looking into that now. I have a good working framework at the moment and swapping screens for an existing one should work without too much trouble.

But let me ask about “expensive”. I come from the mobile world where relatively few “expensive” objects will stop the system. What does “expensive” mean in the context of Roku? Even if I went with individual roScreens, I can’t imaging having more than 3 or 4 deep.

Generally speaking, there is no reason to stack roScreens, especially double buffered screens, since you will typically be redrawing everything on the screen once every 30th of a second. Expensive as I understand it in this context is, there is a limit to the amount of graphics memory available and you are using it up fast. It is also expensive in time: instantiating a new roScreen is pretty slow, but you can redraw an entire roScreen in a few milliseconds.

  • Joel

I refactored it all to use the same screen last night. That actually works better for my other non-screen components that can fit in teh same model (navbar, for example).

Thanks!