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: 
jaxim
Level 7

How to create a Singleton PAttern in BrightScript?

I'd like to create a script with global functions that are both available to my main global script and my scenes. If this were any other programming language, I'd create a Singleton class and call it from anywhere in my code. How do i do this in BrightScript? Can you provide a code example?
0 Kudos
9 Replies

Re: How to create a Singleton PAttern in BrightScript?

In SceneGraph the closest thing I could think of would be to create a custom component of which you store an instance in m.global. It's not exactly the same thing, but it is possible to get close to what you would want to achieve.
0 Kudos
jaxim
Level 7

Re: How to create a Singleton PAttern in BrightScript?

How do the scripts in the scenes access m.global?

I create a global variable in the main script ("m.testParam='test' ") and then when I call it within a scene script, the testParam parameter comes up as invalid
0 Kudos
jaxim
Level 7

Re: How to create a Singleton PAttern in BrightScript?

I just noticed you referred to m.global. This is what I did to set up m.global...


    m.screen = CreateObject("roSGScreen")
    m.global = m.screen.getGlobalNode() 
    m.global.testing= "this is a test"




m.global.testing is still set as invalid
0 Kudos
jaxim
Level 7

Re: How to create a Singleton PAttern in BrightScript?

I just realized that I needed to add the "testing" param to the global  object using the following method...


m.global.addFields( {testing: "this is a test" } ) 



Now m.global.testing returns a valid value. 

I will now check if there are other problems...
0 Kudos
EnTerr
Level 8

Re: How to create a Singleton PAttern in BrightScript?

"siekermantechnology" wrote:
In SceneGraph the closest thing I could think of would be to create a custom component of which you store an instance in m.global. It's not exactly the same thing, but it is possible to get close to what you would want to achieve.

Nope. You can't!

The answer is simple: there is no <censored/> way to share functions between RSG threads.
Which is really ironic - because if there is one thing that Brightscript should be better for multithreading than other languages, it's the lack of function scope^  - meaning there is no principal problem in sharing functions between threads (main v. render v. tasks) since functions are semanthicly constant/literals and thus no thread locks will be needed on invocation! In other words, there is no reason whatsoever why there could not be "function singletons".

Moreover, RSG simply does not support function fields! It does not now, nor will it in the coming rOS 7.5 - and from the looks of it, they have no intent to!
"Bless the Maker and His water!"
I have asked for it, i have advocated for it in this forum... no reply. I talked 1:1 to couple of the dev.relators (realtors?) - but they did not relate. I am afraid they did not understand the issue/need. Particularly the scoping advantage of B/S i know went a total "whoosh!".

(^) no lexical nor nor dynamic scope, no closures. Yes, you have the "m" (self/this) but that is set as part of invocation
0 Kudos
brybott
Level 7

Re: How to create a Singleton PAttern in BrightScript?

It's not exactly a singleton, but I believe you can do what you want (create a function that is accessible to both the 'main' and scene graph threads) if you just include the .brs script file you want to access in the scene graph component's script tags. Even if the .brs script file resides in pkg:/source (where it can also be accessed via the 'main' thread).
0 Kudos
Dhir_Pratap
Level 7

Re: How to create a Singleton PAttern in BrightScript?

Solution mentioned by brybott works. You can include the common brs file in the scene graph node by pointing it in the uri property of script tab. 

Something like 

<script type="text/brightscript" uri="pkg:/source/utils.brs" />
0 Kudos
jaxim
Level 7

Re: How to create a Singleton PAttern in BrightScript?

I can include a common brs file, but that doesn't seem to save the values of variables across multiple scenes /scripts.

The following is what I tried to do but the methods referenced in the associative array return as invalid:


Function Utils() as Object
   m.obj = createobject("roAssociativeArray")
    m.obj.testing = Function()
      end Function
   Function reset()
    end Function


    this = {
       obj: m.obj,
        testMethod: m.obj.testing, 
        reset: resetCode
    }
    return this
end Function



So the following returns as invalid
Reporting().testMethod
Reporting().reset



 However, the following does NOT return as invalid

Reporting().obj

What am I doing wrong?
0 Kudos
EnTerr
Level 8

Re: How to create a Singleton PAttern in BrightScript?

"jaxim" wrote:
The following is what I tried to do but the methods referenced in the associative array return as invalid:
[...]
What am I doing wrong?

You are doing nothing wrong. It's just that "Roku Scene Graph" imperial new clothes do NOT allow first-class functions. That is, RSG cannot have fields of type function. And to add insult to the injury, RSG does not throw error or a warning - it silently strips them from anything you store in a field and pretends nothing happened.

Yes, you are quite right to expect functions should be passable around like in most all programming languages. And no (you are welcome to try) - you cannot out-smart RSG and store them deep within a nested array or associative array (you are welcome to try) - it will "find" them and it will strip them. There is no way around that. See the list of the RSG-approved field types here

I have been talking about function fields for a while, e.g. see viewtopic.php?f=34&t=95412 and viewtopic.php?f=34&t=95290. I am not sure i was understood correctly by the intermediaries re what "first-class function" means and why it matters - but by now i am sure it will not be coming in the next firmware version... and possibly never.

There is a distinction to make, lest the wrong thing be blamed: this is not a Roku language issue - it is a library issue!
Brightscript does support first-class functions just fine, you can assign them as variables, pass them around, use them as m-methods. 
Rather, 'tis the RSG library that does not support functions properly.
0 Kudos