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

Creating RAF instance - in Task and not

Hello and greetings.

I try to use RAF. 

When I invoke Roku_Ads() in the main thread (main.brs -> showChannelSGScreen () ) , RAF instance created fine, all methods on-the-place:
{
    adpodcache: invalid
    adpodcacheupdated: false
    adurl: ""
    clearadbufferscreenlayers: <Function: roku_ads_clearadbufferscreenlayers>
    drawadbufferingprogressbar: <Function: roku_ads_drawadbufferingprogressbar>
    enableadbuffermessaging: <Function: roku_ads_enableadbuffermessaging>
    enablegarbagecollection: <Function: roku_ads_enablegarbagecollection>
    enablenielsendar: <Function: roku_ads_enablenielsendar>
...


But, the I create in in the Task, all methods are invalid:
{
    adpodcache: invalid
    adpodcacheupdated: false
    adurl: ""
    clearadbufferscreenlayers: invalid
    drawadbufferingprogressbar: invalid
    enableadbuffermessaging: invalid
    enablegarbagecollection: invalid
    enablenielsendar: invalid


Why? Where is a problem?

The code in the Task, if it is useful:
sub createAds()
    m.top.ads = Roku_Ads()
end sub

Where 'ads' definition is:
<interface>
<field id="ads" type="assocarray" />
</interface>

0 Kudos
12 Replies
EnTerr
Level 8

Re: Creating RAF instance - in Task and not

That's very interesting. Can you please tell me all places where you invoke Roku_Ads()? And where is the first place you call it? Is it possible you do that in the render thread?
0 Kudos
Veeta
Level 7

Re: Creating RAF instance - in Task and not

Don't assign it to `m.top.ads`.  Assign it to the internal 'm', as in `m.ads`.  Assigning the AA to a node field does the thread-safe filtering of functions you see here.  Also, I think instantiating RAF in a task is only supported as of 2.0, so be sure that is the version you see reported on the console.
0 Kudos
EnTerr
Level 8

Re: Creating RAF instance - in Task and not

"Veeta" wrote:
Don't assign it to `m.top.ads`.  Assign it to the internal 'm', as in `m.ads`.  Assigning the AA to a node field does the thread-safe filtering of functions you see here.

Great catch, Veeta!
And a most amusing, ummm behavior.

Btw, one does not need really to persist the Roku_Ads() result. Calling it repeatedly is "cheap" so just assign it in local variable (e.g. `ads` and not `m.ads`) every time needed.

Also, I think instantiating RAF in a task is only supported as of 2.0, so be sure that is the version you see reported on the console.

Yes, that is the new feature of 2.0 i hear about - plus passing the RSG Node as a 3rd parameter (`view`) where you want the ads to temporarily hang their UI. I believe 2.0 is already on all Roku players already though (well maybe except Sky), being separate from the firmware update schedule.
0 Kudos
Veeta
Level 7

Re: Creating RAF instance - in Task and not

Another note for implementing RAF in a Task thread.  Google did it for their DAI SDK, which has a Roku implementation.  Find the details at https://support.google.com/dfp_premium/answer/7298842?hl=en , look at the SceneGraph example.
0 Kudos
EnTerr
Level 8

Re: Creating RAF instance - in Task and not

This shows RAF used from a Task:
https://github.com/rokudev/RAF4RSG-sample
0 Kudos
mape
Level 7

Re: Creating RAF instance - in Task and not

"Veeta" wrote:
Don't assign it to `m.top.ads`.  Assign it to the internal 'm', as in `m.ads`.  Assigning the AA to a node field does the thread-safe filtering of functions you see here.  Also, I think instantiating RAF in a task is only supported as of 2.0, so be sure that is the version you see reported on the console.

I don't understand, how to do this. m here is a task, and I think to assign Roku_Ads instance to the field. m.top.ads in a field. If I assign it to m.ads, the 'observeField' will not work. 
And yes, RAF version is 2.0.
0 Kudos
mape
Level 7

Re: Creating RAF instance - in Task and not

"EnTerr" wrote:
This shows RAF used from a Task:
https://github.com/rokudev/RAF4RSG-sample

That's interesting, thank you. But I can't define main difference (with my code) yet. Will looking more...
0 Kudos
mape
Level 7

Re: Creating RAF instance - in Task and not

"EnTerr" wrote:
That's very interesting. Can you please tell me all places where you invoke Roku_Ads()? And where is the first place you call it? Is it possible you do that in the render thread?

1st place (successfully):
main.brs:
sub showChannelSGScreen()
    screen = CreateObject("roSGScreen")
    m.port = CreateObject("roMessagePort")
    screen.setMessagePort(m.port)
    scene = screen.CreateScene("MainScene")
    screen.show()
    MakeSome() '<---- HERE


Where MakeSome() stored in athother file, same filder, name mixin.brs:
sub MakeSome()

    ads = Roku_Ads()


Errorneous creation:
Task xml:
<?xml version="1.0" encoding="UTF-8"?>
<component name="CreateAdsTask" extends="Task" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">
<script uri="pkg:/components/CreateAdsTask.brs" />
<interface>
<field id="ads" type="assocarray" />
</interface>
</component>


Task script:
Library "Roku_Ads.brs"

Sub Init()
  m.top.functionName = "createAds"
End Sub

sub createAds()
    m.top.ads = Roku_Ads()
end sub

Invoking - in the main Scene (only one scene present in project):
    m.adsTask = createObject("RoSGNode", "CreateAdsTask")
    m.adsTask.observeField("ads", "setAds")
[size=85][font=Helvetica Neue, Helvetica, Arial, sans-serif]    m.adsTask.control = "RUN"[/font][/size]


setAds:
sub setAds()

    m.ads = m.adsTask.ads


Where m is current Scene. 
0 Kudos
mape
Level 7

Re: Creating RAF instance - in Task and not

"EnTerr" wrote:
Btw, one does not need really to persist the Roku_Ads() result. Calling it repeatedly is "cheap" so just assign it in local variable (e.g. `ads` and not `m.ads`) every time needed.

Really? Sounds good.
But, i think to separate it to the Task will be useful to share it between different Scenes and Players. 
0 Kudos