Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
nickchavez
Binge Watcher

Passing an assocarray with function fields through callFunc on an interface functional field

Hi all,

Back with another question 🙂

I'm noticing that when I try to pass an assocarray through callFunc on an interface's functional field, the assocarray keeps all its key values (nodes, primitive values) but it loses any function values, these becoming `Invalid`. For example, if I have this `FooFactory` component:

 

 

<component name="FooFactory" extends="Node">
<interface>
  <function name="makeFoo" />
</interface>
<script type="text/brightscript"><![CDATA[
  function makeFoo() as Object
    foo = {}
    foo.bar = 123
    foo.baz = "hello"
    foo.stringify = function()
      return "bar: " + m.bar.toStr() + " baz: " + m.baz
    end function
    return foo
  end function
]]></script>
</component>

 

and then I use this in another component, like so:

 

<component name="MyScene" extends="Scene">
<script type="text/brightscript"><![CDATA[
  sub init()
    factory = createObject("roSGNode", "FooFactory")
    foo = factory.callFunc("makeFoo")
    print foo.bar ' This works!
    print foo.baz ' This works!
    print foo.stringify() ' This crashes!
  end sub
]]></script>
</component>

 

 

And this crashes because `foo.stringify` has become `Invalid` (though still present as a key) while the other int and string members, are still there. Specifically, the error is:

Member function not found in BrightScript Component or interface.

 

Any advice on how to make this work, or how to achieve something similar, where one component can return an "object" with methods to another component?

0 Kudos
4 REPLIES 4
sanity-check
Roku Guru

Re: Passing an assocarray with function fields through callFunc on an interface functional field

I never found a way to do this with assocarrays, it's a bit frustrating coming from other languages.

If you pass nodes around instead of assocarrays, you can do foo.callFunc("stringify", {}).

Of course nodes are more painful to deal with, so it's not exactly ideal.

My strategy is to process incoming data as asocarrays within a single component then transform everything into node trees for use elsewhere in the app. No idea how other people approach it.

 

0 Kudos
jasonxz
Newbie

Re: Passing an assocarray with function fields through callFunc on an interface functional field

I'm pretty new to this (been working on my 1st project for about a week, now) but I've started just making all of my classes components that extend Node. Things seem to play nicer that way.  🤷‍♂️

0 Kudos
nickchavez
Binge Watcher

Re: Passing an assocarray with function fields through callFunc on an interface functional field

Interesting re: doing everything as a Node. Is that the recommended approach? Is anyone aware of the performance overhead from using Nodes vs plain objects (I assume there is some)?

0 Kudos
sanity-check
Roku Guru

Re: Passing an assocarray with function fields through callFunc on an interface functional field

Kind of... The docs mention AA vs Nodes here:

https://developer.roku.com/en-gb/docs/developer-program/performance-guide/data-management.md#data-mo...

In reality creating a node takes an order of magnitude or two longer than creating an AA so depending on how much you're passing them around the overall perf hit might or might not balance out.

My thinking, though, is that most (all?) of the big objects we're passing around are destined for RowLists etc anyway, in which case they need to be turned into ContentNode trees eventually - so I just do it early. For smaller bits of data it doesn't matter if it takes 8ms to create a single AA or 80ms to create a single Node, if it's happening once every few minutes rather than 200 times in a loop.

0 Kudos