Reputation: 475
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
Reputation: 16338
I think you can do this with 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
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
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