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: 
SoN9ne
Visitor

Call Operator ( ) attempted on non-function | .brs loading

Hello,

I am new to Roku development and I am running into an issue where I have a function that is not being called properly and it makes me question how the .brs files are loaded.

I read somewhere, although I cannot seem to locate where, that all .brs files are loaded in the channel and readily available. Is this true? If so, is it a better procedure to have the .brs files in an includes directory and "run" the file when you need it? Do I need to worry about running a .brs file more than once? I would assume so, there isn't any run_once method so I would have to build my logic for this? I don't want all files loaded as this seems to cause unnecessary overhead. Any information on how the files are processed/loaded would be useful as I cannot seem to locate this information currently.

Here's my problem. I currently have a blank channel with nothing but a roListScreen with set options. Each options has it's own callback and when I fire the callback any function in these callbacks doesn't seem to work. Below is the code I am using to see if anyone could point out what I may be doing wrong. I have the debug output at the bottom.

All .brs files are in the pkg:/source directory

main.brs
' ******************************************************************
' * This is the main function, this is the channel's starting point
' ******************************************************************
Sub Main()
print "Channel Initialized - ";
' Create screen and event listener port (roMessagePort)
screen = CreateObject("roListScreen")
port = CreateObject("roMessagePort")
' Set lister port to screen
screen.SetMessagePort(port)
' Initialize the theme
InitTheme()
' Set screen content title
screen.SetHeader( tr("Welcome to the Olympusat Template") )
' Initialize content list (main page)
contentListOptions = MainContentList()
' Assign the content list to the screen
screen.SetContent(contentListOptions)
' Show the content list
screen.show()
' Keep channel open and monitor event listener
while (true)
' Define event
event = wait(0, port)
' Check if current screen event
if (type(event) = "roListScreenEvent")
print "----------------------[ Main Page | roListScreenEvent ]----------------------"
' Check for focused item
if (event.isListItemFocused())
print "Calling Title for index: " ; event.GetIndex()
' Update breadcrumb
screen.SetBreadcrumbText(tr("Menu"), contentListOptions[event.GetIndex()].Title)
print "Calling Title Complete"
else if (event.isListItemSelected())
print "Calling Callback for index: " ; event.GetIndex() ; " - " ; contentListOptions[event.GetIndex()].Title
' Do callback when selected
contentListOptions[event.GetIndex()].CallBack()
print "Callback Complete"
endif
endif ' End Check for events
end while ' End Keep channel open
End Sub

' Checks if display is HD
Function IsHD() As Boolean
di = CreateObject("roDeviceInfo")
if di.GetDisplayType() = "HDTV"
print "HDTV"
return true
else
print "Regular TV"
return false
end if
End Function

' Gets the current locale
Function getLocale() As String
di = CreateObject("roDeviceInfo")
return di.GetCurrentLocale()
End Function


MainContentList.brs - It should be noted that I didn't have to do the anonymous function for the callback (omitting the '()' ) but for some reason today I had to put the callback in the anonymous function. Commented out icons for now.
' Build the list of options for the main page
Function MainContentList() as object
print "MainContentList Start - ";
contentList = [
{
Title: tr("Live Stream"),
ID: "1",
'SDSmallIconUrl: "pkg:/locale/default/images/live_stream_small.png",
'HDSmallIconUrl: "pkg:/locale/default/images/live_stream_small.png",
'HDBackgroundImageUrl: "pkg:/locale/default/images/live_stream_large.png",
'SDBackgroundImageUrl: "pkg:/locale/default/images/live_stream_large.png",
ShortDescriptionLine1: tr("Live Stream"),
ShortDescriptionLine2: tr("Watch our live stream"),
CallBack: Function()
LiveStream()
End Function
},
{
Title: tr("On Demand"),
ID: "2",
'SDSmallIconUrl: "pkg:/locale/default/images/on_demand_small.png",
'HDSmallIconUrl: "pkg:/locale/default/images/on_demand_small.png",
'HDBackgroundImageUrl: "pkg:/locale/default/images/on_demand_large.png",
'SDBackgroundImageUrl: "pkg:/locale/default/images/on_demand_large.png",
ShortDescriptionLine1: tr("On Demand"),
ShortDescriptionLine2: tr("View our on demand options"),
CallBack: Function()
OnDemand()
End Function
},
{
Title: tr("Alt-language Stream"),
ID: "3",
'SDSmallIconUrl: "pkg:/locale/default/images/alt_stream_small.png",
'HDSmallIconUrl: "pkg:/locale/default/images/alt_stream_small.png",
'HDBackgroundImageUrl: "pkg:/locale/default/images/alt_stream_large.png",
'SDBackgroundImageUrl: "pkg:/locale/default/images/alt_stream_large.png",
ShortDescriptionLine1: tr("Alt-language Stream"),
ShortDescriptionLine2: tr("Alt-language Stream Description"),
CallBack: Function()
AltLangStream()
End Function
},
{
Title: tr("About Us"),
ID: "4",
'SDSmallIconUrl: "pkg:/locale/default/images/about_small.png",
'HDSmallIconUrl: "pkg:/locale/default/images/about_small.png",
'HDBackgroundImageUrl: "pkg:/locale/default/images/about_large.png",
'SDBackgroundImageUrl: "pkg:/locale/default/images/about_large.png",
ShortDescriptionLine1: tr("About Us"),
ShortDescriptionLine2: tr("Some basic information about us"),
CallBack: Function()
AboutUs()
End Function
}
]
print "MainContentList End - "
return contentList
End Function


LiveStream.brs
Sub LiveStream()
print "LiveStream Start"
locale = getLocale()
print "Locale is: " ; locale
if ("es_ES" = locale) then
SpanishStream()
else
print "Using Default"
' English is default
EnglishStream()
end if
print "LiveStream End"
End Sub


EnglishStream.brs - Spanish is exactly the same, except the name respectively
Sub EnglishStream()
print "EnglishStream Start"

print "EnglishStream End"
End Sub


This is the output of the debugger (not sure why the "Calling Title for index: 0" is called so many times on channel start)
------ Running ------
Channel Initialized - InitTheme Start - InitTheme End - MainContentList Start - MainContentList End -
----------------------[ Main Page | roListScreenEvent ]----------------------
Calling Title for index: 0
Calling Title Complete
----------------------[ Main Page | roListScreenEvent ]----------------------
Calling Title for index: 0
Calling Title Complete
----------------------[ Main Page | roListScreenEvent ]----------------------
Calling Title for index: 0
Calling Title Complete
----------------------[ Main Page | roListScreenEvent ]----------------------
Calling Title for index: 0
Calling Title Complete
----------------------[ Main Page | roListScreenEvent ]----------------------
Calling Title for index: 0
Calling Title Complete
----------------------[ Main Page | roListScreenEvent ]----------------------
Calling Callback for index: 0 - Live Stream
BrightScript Micro Debugger.
Enter any BrightScript statement, debug commands, or HELP.

Current Function:
014: Function()
015: LiveStream()
016: End Function
Function Call Operator ( ) attempted on non-function. (runtime error &he0) in ...g:/source/mainContentList.brs(15)
015: LiveStream()
Backtrace:
Function $anon_17df() As Dynamic
file/line: /tmp/plugin/JKCAAAUeb0r5/pkg:/source/mainContentList.brs(15)
Function main() As Void
file/line: /tmp/plugin/JKCAAAUeb0r5/pkg:/source/main.brs(37)

Local Variables:
global &h0020 rotINTERFACE:ifGlobal
m &h0010 bsc:roAssociativeArray, refcnt=3
livestream &h0000 <uninitialized> val:Uninitialized
BrightScript Debugger>


Thanks for any help you can provide.
0 Kudos
3 REPLIES 3
EnTerr
Roku Guru

Re: Call Operator ( ) attempted on non-function | .brs loadi

Most likely LiveStream.brs is missing from your ZIP. As troubleshooting steps,
  • put all .brs files in the same directory where main.brs is.

  • re-build the zip and check what is inside before deploying

  • just put all functions in main.brs and worry about chopping it later


On a side note,
{
'no need to do this:
CallBack: Function()
LiveStream()
End Function

'this will do:
CallBack: LiveStream
}
0 Kudos
SoN9ne
Visitor

Re: Call Operator ( ) attempted on non-function | .brs loadi

"EnTerr" wrote:

On a side note,
{
'no need to do this:
CallBack: Function()
LiveStream()
End Function

'this will do:
CallBack: LiveStream
}


This is what I did originally but then it started throwing errors. I was able to get this working again by starting over on a backup. the .brs was in the zip which is what was so confusing.

So do all .brs files get loaded when the app starts? I have reasons for not wanting all the .brs files to be loaded this is why I am asking.

Thanks for your help
0 Kudos
EnTerr
Roku Guru

Re: Call Operator ( ) attempted on non-function | .brs loadi

It would seem "yes", asked before here viewtopic.php?f=34&t=46836#p317906
0 Kudos