rokubrightscriptscenegraph

Is it possible to assign an anonymous function to a global associative array property?


New to roku/brightscript development: Is it possible to add an object to the global associative array (accessible by all components), that has a method defined as one of the properties, and call that method?

Main.brs:

function Main()
    init()
end function

function init()    
    screen = createObject("roSGScreen") 
    m.port = createObject("roMessagePort")
    screen.SetMessagePort(m.port)

    scene = screen.CreateScene("MainController")
    screen.show()

    o = {
        getName: function() as string
            return "John"
        end function
    }

    setUpGlobal(screen)
    m.global.addFields({mainMethods: o})        

    while(true)
        msg = wait(0, m.port)
        msgType = type(msg)

        if msgType = "roSGScreenEvent"
            if msg.isScreenClosed() then exit while
        end if    
    end while        
end function

function setUpGlobal(p_screen as Object)
    m.global = p_screen.getGlobalNode()
    m.global.id = "GlobalNode"
end function

.. then in another MainController, after running a task and returning data...

MainController.brs

function init()
    loadConfig()
end function


function loadConfig()
    m.config = createObject("roSGNode", "Configurator")
    m.config.observeField("done", "onConfigLoaded")
    m.config.observeField("fail", "onConfigError")
end function 


function onConfigLoaded()
    print "config loaded: " + m.global.mainMethods.getName()
end function


function onConfigError()
    print "config failed to loaded"
end function

When it hits line 16 of MainController, I get this:

Member function not found in BrightScript Component or interface. (runtime error &hf4) in pkg:/components/MainController.brs(16)

This is just a general test of what can/can't be done so please don't comment on whether this is "good practice" or not. I just want to know if it's possible and if so, what am I missing here? Thanks for any help


Solution

  • You can have functions as roAssociativeArray values. In fact that is how OO methods are done in BrightScript.

    However, you cannot assign functions to fields of a Roku Scene Graph object (roSgNode derivatives)! Either directly or indirectly (nested). It's a limitation of the (current?!) implementation.

    You can see list of the field types supported by RSG here https://sdkdocs.roku.com/pages/viewpage.action?pageId=1608549

    Yes, it does say to support assocarray and (as of lately) array - but there is a caveat to that! When you assign (or even access) compound objects between threads, a deep copy is made and only the "supported" types make it through - and as you experienced, function is not one of them. All unrecognized data is currently silently dropped, with not even whisper of a warning - so buyer beware.

    See https://forums.roku.com/viewtopic.php?f=34&t=96955&p=541965#p541965 for more. Feel invited to add your voice in Roku's developer forum, requesting support of function type by RSG - they tend to listen if enough people complain.