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: 
Photovor
Visitor

Using registry values inside dialog?

So I'm using the new ScreenGraph APIs, and I'm showing a keyboarddialog, and I want to pre-set the text (and then save any changed text) from the registry. Any anyone provide an example of how I would do that?

My keyboard dialog looks like this:
function showdialog()
    keyboarddialog = createObject("roSGNode", "KeyboardDialog")
    keyboarddialog.backgroundUri = "pkg:/images/rsgde_dlg_bg_hd.9.png"
    keyboarddialog.buttons=["Save","Cancel"]
    keyboarddialog.title = "Enter Location ID"
    keyboarddialog.text = ScreenID
    m.top.dialog = keyboarddialog
end function


ScreenID would be blank on the first time this dialog appeared, but would then be set to the text that they entered from this screen every time after. I need this to persist in the registry.
0 Kudos
8 REPLIES 8
RokuNB
Roku Guru

Re: Using registry values inside dialog?

You are prevented from creating (and because of that, having) a roRegistrySection object in the scene graph thread. Because of that you'll have to do registry handling either in the main or a task thread.

See https://sdkdocs.roku.com/display/sdkdoc ... pt+Support
0 Kudos
belltown
Roku Guru

Re: Using registry values inside dialog?

Generally, I store my registry data as an roAssociative array formatted as a single JSON string.

I read the registry on startup in Main(), storing what I need in global data.

When I need to write to the registry from within a Scene, I use a Task node.

Here's an example function to read, called from within Main():

function getConfig() as Object
   config = {}
   registrySection = CreateObject("roRegistrySection", "MyChannel")
   configString = registrySection.Read("config")
   if configString = ""
       print "getConfig. No config registry info found"
   else
       config = ParseJson(configString)
       if Type(config) <> "roAssociativeArray"
           print "getConfig. Expecting roAssociativeArray, found: "; Type(config)
           config = {}
       end if
   end if
   return config
end function

Here's  the code in components/TaskRegistry.xml

<?xml version="1.0" encoding="UTF-8"?>
<component name="TaskRegistry" extends="Task">
 <script type="text/brightscript" uri="pkg:/components/TaskRegistry.brs" />
 <interface>
   <field id="write" type="assocarray" />
 </interface>
</component>

and in components/TaskRegistry.brs

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

sub taskRun()
   registrySection = CreateObject("roRegistrySection", "MyChannel")
   if Type(m.top.write) <> "roAssociativeArray"
       print "TaskRegistry.brs. taskRun(). m.top.write expecting roAssociativeArray, found: "; Type(m.top.write)
   else
       value = FormatJson(m.top.write)
       if value = ""
           print "TaskRegistry.brs. taskRun(). FormatJson error"
       else
           if not registrySection.Write("config", value)
               print "TaskRegistry.brs. taskRun(). roRegistrySection Write error"
           else if not registrySection.Flush()
               print "TaskRegistry.brs. taskRun(). roRegistrySection Flush error"
           end if
       end if
   end if
end sub

To use TaskRegistry, include the following in your Scene's component:

<TaskRegistry id="taskRegistry" />

and write to the registry using the following code:

' Code in init() '
m.taskRegistryNode = m.top.findNode("taskRegistry")

' Code in event-handler '
config =  {
         key1: 42
         key2: "Forty Two"
         key3: ["blah", "blah"]
         }
m.taskRegistryNode.write = config
m.taskRegistryNode.control = "RUN"
0 Kudos
Photovor
Visitor

Re: Using registry values inside dialog?

Thank you belltown, that's exactly what I needed. Been trying to hack this together for a while now, since there are no good examples or documentation on how to do this effectively.
0 Kudos
Photovor
Visitor

Re: Using registry values inside dialog?

I'm still having a slight issue with accessing the config array from my screengraph screen.

In main() I do this:
sub Main()
    m.config = getConfig()
    showChannelSGScreen()
end sub

function getConfig() as Object
    print "Getting Registry Values"
    config = {}
    registrySection = CreateObject("roRegistrySection", "CampusSignage")
    configString = registrySection.Read("config")
    if configString = ""
        print "getConfig. No config registry info found"
    else
        config = ParseJson(configString)
        if Type(config) <> "roAssociativeArray"
            print "getConfig. Expecting roAssociativeArray, found: "; Type(config)
            config = {}
        end if
    end if
    return config
end function

 And that gets my config as a global, but I can't access that inside my Screen.
0 Kudos
belltown
Roku Guru

Re: Using registry values inside dialog?

In Main(), you need to gain access to the Global Node, which is a global super-node that's global to everything in the entire Scene Graph Application (https://sdkdocs.roku.com/display/sdkdoc/Scene+Graph+Data+Scoping). You can call your Main's Global Node reference anything you like. Roku documentation uses "m.global" (which defines a property in the BrightScript global associative array -- which is only accessible from the Main thread). Personally, I just use a local variable called "g" in Main().


screen = CreateObject("roSGScreen")
.
.
m.global = screen.getGlobalNode()

Then you need to create a field (or fields) in the Global Node for your config data:


m.global.addField("config", "assocarray", false)

Then you need to assign your config object to the config field you created in the Global Node:


m.global.config = getConfig()

In your Scene code, you can reference fields in the Global Node like so (Note that the use of "m.global" in a Scene, versus in Main(), is required; you can't call it something else):


print "global config: "; m.global.config
0 Kudos
btpoole
Channel Surfer

Re: Using registry values inside dialog?

"belltown" wrote:
In Main(), you need to gain access to the Global Node, which is a global super-node that's global to everything in the entire Scene Graph Application (https://sdkdocs.roku.com/display/sdkdoc/Scene+Graph+Data+Scoping). You can call your Main's Global Node reference anything you like. Roku documentation uses "m.global" (which defines a property in the BrightScript global associative array -- which is only accessible from the Main thread). Personally, I just use a local variable called "g" in Main().


screen = CreateObject("roSGScreen")
.
.
m.global = screen.getGlobalNode()

Then you need to create a field (or fields) in the Global Node for your config data:


m.global.addField("config", "assocarray", false)

Then you need to assign your config object to the config field you created in the Global Node:


m.global.config = getConfig()

In your Scene code, you can reference fields in the Global Node like so (Note that the use of "m.global" in a Scene, versus in Main(), is required; you can't call it something else):


print "global config: "; m.global.config


belltown thanks so much for the example. Using your code was great for my app but I do have a question. I am trying to delete one of the elements of the config as follows
m.global.config.delete("mylist")
print m.global.config

When I do the above the print still shows the "mylist" as being part of the config. Is there something missing? Thanks for any help
0 Kudos
belltown
Roku Guru

Re: Using registry values inside dialog?

.....
0 Kudos
btpoole
Channel Surfer

Re: Using registry values inside dialog?

"belltown" wrote:
"btpoole" wrote:
belltown thanks so much for the example. Using your code was great for my app but I do have a question. I am trying to delete one of the elements of the config as follows
m.global.config.delete("mylist")
print m.global.config

When I do the above the print still shows the "mylist" as being part of the config. Is there something missing? Thanks for any help

Try:


m.global.config.removeField("mylist")

See https://sdkdocs.roku.com/display/sdkdoc/ifSGNodeField#ifSGNodeField-removeField(fieldNameasString)as...

I see my mistake. I was only removing or deleting the mylist from global but not really deleting it from the registry section it was stored in, so each time app started it was getting it from the registry. Thanks again for the code.
0 Kudos