Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
EnTerr
Level 8

Ground Control to SGt Node: assign event/functions, how?

I am ready on scenography and then i reach this exciting section:
"BrightScript/XML Markup Equivalence" wrote:
... you can also create and add nodes to the Scene Graph tree dynamically in BrightScript as needed for your application (for example, in response to user input). You can also configure existing or new nodes in the Scene Graph tree at any time in BrightScript. When and how you create and configure the Scene Graph node tree scene in your application XML files should depend on the intended flow of your Scene Graph application.
[...]
But a node can be created in BrightScript at any time, using functions like CreateObject() and createChild(); you don't have to use XML markup at all if your application is easier to write by creating Scene Graph nodes dynamically as needed.

That's great! I am all hot and bothered to do that from B/S. Everything else seems to fit but i am missing a piece i cannot figure out so far,
how do i assign functions to events like init() and onKeyEvent() when not using XML?

RTFM forgot to mention that. It's not like compiled function objects are any concern to threads, since B/S has no lexical scoping, there are no closures that can drag data with them and thus no dirty variables, no race conditions... i should be able to simply assign it like so, right?
node.onKeyEvent = function(key, isPressed): ? key, isPressed: end function
To top it off, anonymous functions are actually p-code literals so even if i was doing such assignments in a loop all day long, that would neither cause repeat parsing nor new memory to be allocated - since that's a literal in B/S, just like "string literal" is. Beautiful.

That's best case scenario - but baring that, how do i "inject" contents of a <SCRIPT/> into a B/S created node?
0 Kudos
9 Replies
Highlighted
TheEndless
Level 7

Re: Ground Control to SGt Node: assign event/functions, how?

As far as I'm aware, you still have to have an XML file that defines the component, otherwise SceneGraph won't be able to find the component you're trying to create. I don't think there's any way to register a component with SceneGraph via code.

To minimize the XML as much as possible, you could do something like this:
<?xml version="1.0" encoding="utf-8" ?>
<component name="myComponent" extends="Group">
<script type="text/brightscript" uri="pkg:/components/myGroup.brs" />
</component>

Then put all of your code in myGroup.brs, which will include your component specific init() and onKeyEvent() functions. Note that those are not methods on the component itself, but rather intrinsic event handler functions.
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
EnTerr
Level 8

Re: Ground Control to SGt Node: assign event/functions, how?

"TheEndless" wrote:
As far as I'm aware, you still have to have an XML file that defines the component, otherwise SceneGraph won't be able to find the component you're trying to create. I don't think there's any way to register a component with SceneGraph via code.

You mean if i want to "extend" an existing component?! I don't want to do that... why would i?

I don't want to sub-class existing nodes, i am not writing a future-reuse library - i am happy to use off-the-shelf "as-is" nodes. All i want is to instantiate and populate them programmatically, then use them! I can do that with the children, can do that for the attributes and all i seem to miss is the functions/script, right?

... specific init() and onKeyEvent() functions. Note that those are not methods on the component itself, but rather intrinsic event handler functions.

tOmato, tomAto - it's a question of what you name them. Event handlers which are functions that get invoked by magic-name... call them methods or not, it would be best they get accessible name slots in the node, so they can be assigned to or called directly... no?
0 Kudos
TheEndless
Level 7

Re: Ground Control to SGt Node: assign event/functions, how?

"EnTerr" wrote:
You mean if i want to "extend" an existing component?! I don't want to do that... why would i?

I'd expect at the very least you'd want to extend a Scene node, but if not, you still need a way to hook into it's context, and there's no way to do that without extending it. Additionally, if you want to take advantage of the multi-threading capabilities of SceneGraph, then you'll have to extend the Task node. It can't be used generically, because the "functionName" has to be the name of a function that is defined inside the Task's context, which again, can only be established by specifying the <script/> that belongs to that Task. Note that "functionName" is a string, not a function reference.

"EnTerr" wrote:
... specific init() and onKeyEvent() functions. Note that those are not methods on the component itself, but rather intrinsic event handler functions.
tOmato, tomAto - it's a question of what you name them. Event handlers which are functions that get invoked by magic-name... call them methods or not, it would be best they get accessible name slots in the node, so they can be assigned to or called directly... no?

Not exactly. At least in the case of onKeyEvent, it doesn't belong to the node. It's an event handler that is registered to observe some global event that isn't exposed elsewhere. Its presence in the component's code is only to establish context within that node's global AA, which you do not have access to outside of that component. The key event walks up the focus chain until one of the components' onKeyEvent listeners says it has handled the event, so you'll need code running somewhere in the context of one of those components if you want to respond to key events.

So, modifying my code above slightly, I still believe, at the very least, you'd need this XML:
<?xml version="1.0" encoding="utf-8" ?>
<component name="myScene" extends="Scene">
<script type="text/brightscript" uri="pkg:/components/myScene.brs" />
</component>

You could then add an onKeyEvent function to myScene.brs that sets a field on the scene to raise it to the BrightScript thread. Then, in the BrightScript thread, you'd need to set a second field on the Scene, so it knows whether the key press was handled or not.

Honestly, I don't think there's any way you'd be able to create and control a SceneGraph application entirely from the main BrightScript thread without at least some XML. Even if you could, I can't imagine you'd really want to, as every operation would block the UI. If you want to do that, then I'd say it's better to stick with the 2D API.
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
EnTerr
Level 8

Re: Ground Control to SGt Node: assign event/functions, how?

"TheEndless" wrote:
"EnTerr" wrote:
You mean if i want to "extend" an existing component?! I don't want to do that... why would i?

I'd expect at the very least you'd want to extend a Scene node, but if not, you still need a way to hook into it's context, and there's no way to do that without extending it. Additionally, if you want to take advantage of the multi-threading capabilities of SceneGraph, then you'll have to extend the Task node. It can't be used generically, because the "functionName" has to be the name of a function that is defined inside the Task's context, which again, can only be established by specifying the <script/> that belongs to that Task.

Wait - stop for a moment and think what do you really mean by "extend"? What you describe is just the ability to set functions by name for the node (or brute inject a <script/>) - that exactly what i ask for but that is not what "extend" is - extend is a much broader thing!

I think you are having a cognitive bias, in which doing some SG XML programming for a while, it feels to you subclassing is the only - and natural way to do things. It ain't. Imagine for a moment scenography gives me these:
node.setFunction(name as string, fn as function)
node.getFunction(name as string) as function ' optional
node.getFunctions() ' optional, return AA of all functions assoc with a node

Or wait - it could be even simpler, if addField()/setField()/getField() work with functions too, which are primitive type in B/S (SG already supports Integer, Float, Double, String, Boolean - why not Function?) - e.g. as simple as
node.addField("myFunc", "function", false)
node.myFunc = function() ...

The function assigned may be either a fn literal (i.e. anonymous) or a global fn - no matter because functions are thread-safe in B/S, they have no state. This is in stark contrast with most any other programming language where there is lexical scope, closures and such and one cannot "rip" safely a function without dragging some entrails / calls having side (d)effects. Not so in B/S! Moreover function objects are primitive, they do not get garbage collected, so no fear that reference count should be maintained between interp threads. It's about time to rip the benefits of this feature (which in other places has been a handicap)!

Now, if i had this feature (it may already exist for all i know - but if not, it's rather simpler to add) - can you think of a reason i would need to "extend" anything into anything?
0 Kudos
TheEndless
Level 7

Re: Ground Control to SGt Node: assign event/functions, how?

"EnTerr" wrote:
I think you are having a cognitive bias, in which doing some SG XML programming for a while, it feels to you subclassing is the only - and natural way to do things. It ain't.

In SceneGraph, it is, currently (the "only" part, not necessarily the "natural" part).
"EnTerr" wrote:
Now, if i had this feature (it may already exist for all i know - but if not, it's rather simpler to add) - can you think of a reason i would need to "extend" anything into anything?

Nope, but it doesn't exist, which is my point. If you're lobbying that they add such functionality, that's fair enough. I'm just explaining how it works today.

If it does exist, but isn't documented, that's great, and this conversation is rendered moot, but I don't think that's the case.
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
Roku Employee
Roku Employee

Re: Ground Control to SGt Node: assign event/functions, how?

"The Docs Guy " wrote:

It would probably be good for me to revise and clarify the section of documentation that got the guy all “hot and bothered”, since it already needs some clarification anyway.

By “BrightScript”, I meant “BrightScript within an XML component file <script> element CDATA section”, not the “main BrightScript thread”.

You can’t do much with the “main BrightScript thread” except kick off the Scene Graph render thread, that starts in an EXTENDED “Scene” component XML file.

Wishful thinking, thinking based on previous Roku programming models, whatever, it’s the first trap programmers fall into with Scene Graph. One of the first things I wrote about Scene Graph is some totally nonsensical paragraph about being able to create and add any number of “Scenes” in BrightScript using createObject(). (It may still be in there, another thing to fix.)

and

"Lead Roku Scenegraph Engineer" wrote:

You can actually create nodes in the main Brightscript thread. The problem is that it’s generally much slower to do things that way because of all the synchronization that has to be done with the scene graph render thread.

It’s much faster to create nodes in the scripts inside an XML component that extends “Scene” (or in other XML components), since those scripts run in the render thread and avoid synchronization penalties.


Hope that helps

- Joel
0 Kudos
EnTerr
Level 8

Re: Ground Control to SGt Node: assign event/functions, how?

Hey RokuJoel -
thanks for bringing this feedback! Alas, it does not help - since they did not address what was asked about, which is how to "inject" functions into an existing node. Luckily though I think we clarified the issue at hand in discussion with TheEndless (incl. some vigorous exchange behind the scenes) - and it seems there is no way currently in SG to do that.

My request therefore would be to consider adding the ability to dynamically add functions to components just like that can be already done with fields and children - can you pass that one up?

I think the easiest way would be to add "function" value type to the supported SG interface types (it's a primitive type like integer/float/string/boolean - plus immutable) and then to just use addField()/setField(), i.e. treat them as first-class citizens (aka 1st-class functions), see explanation above viewtopic.php?f=34&t=95412#p533852

I know, i know - the first reaction of SG engineer would be to wince, since that would mean functions can be transferred between interpreter contexts/threads - but if they could please, please give it a second thought! - functions are already immutable, non-GC-able literals in B/S, which makes them SAFE to share between threads, with no side effects nor race conditions! No extra compilation either...
0 Kudos
Roku Employee
Roku Employee

Re: Ground Control to SGt Node: assign event/functions, how?

Hmm - what about the thing I posted yesterday- perhaps I need to reread your questions, but I think that might be a similar thing to what you are asking - how to create and add nodes to a scenegraph node from the main brightscript thread?

- Joel
0 Kudos
EnTerr
Level 8

Re: Ground Control to SGt Node: assign event/functions, how?

"RokuJoel" wrote:
Hmm - what about the thing I posted yesterday- perhaps I need to reread your questions, but I think that might be a similar thing to what you are asking - how to create and add nodes to a scenegraph node from the main brightscript thread?

Yes, i already saw one can create Nodes, can add/update data fields and children - everything but adding/updating functions.

Functions seems to be the final piece missing in the puzzle (or it's undocumented), this thread is about them.
0 Kudos