neoRiley
neoRiley

Reputation: 475

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

Upvotes: 3

Views: 1247

Answers (3)

Jonny
Jonny

Reputation: 16338

I think you can do this with anonymous functions.

https://developer.roku.com/en-gb/docs/references/brightscript/language/program-statements.md#anonymous-functions

q = { 
    starring : Function(o, e)
        str = e.GetBody()
        print "Starring: " + str 
        toks = box(str).tokenize(",")
        For Each act In tok
            actx = box(act).trim()
            If actx <> "" Then
                print "Actor: [" + actx + "]"
                o.Actors.Push(actx)
            End If
        End For
        Return 0
    End Function 
} 

q.starring(myobj, myxml)

Upvotes: 0

Nas Banov
Nas Banov

Reputation: 29018

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.

Upvotes: 6

Eugene Smoliy
Eugene Smoliy

Reputation: 954

You can't pass functions in node's fields. Only data. If you check m.global.mainMethods.getName value right after setting it, it will be invalid.

Upvotes: 1

Related Questions