Photovor
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2017
08:54 AM
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:
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.
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.
8 REPLIES 8
NB_
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2017
09:41 AM
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
See https://sdkdocs.roku.com/display/sdkdoc ... pt+Support
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2017
10:47 AM
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():
Here's the code in components/TaskRegistry.xml
and in components/TaskRegistry.brs
To use TaskRegistry, include the following in your Scene's component:
and write to the registry using the following code:
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"
Photovor
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2017
11:58 AM
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.
Photovor
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2017
01:22 PM
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:
And that gets my config as a global, but I can't access that inside my 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.
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2017
03:14 PM
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().
Then you need to create a field (or fields) in the Global Node for your config data:
Then you need to assign your config object to the config field you created in the Global Node:
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):
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
btpoole
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2017
06:49 AM
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
belltown
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2017
07:16 AM
Re: Using registry values inside dialog?
.....
btpoole
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-21-2017
05:38 AM
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 followsm.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.