brightscript: Task node function


A task node function is , e.g. eventLoopFunction() in m.myTask.functionName = “eventLoopFunction”
Source code to demo this is attached.

eventLoopFunction has its own m, and have access to a copy of task’s m.
This is demo’d in m.dataCreatedByInit and m.dataCreatedByLoopFunction
eventLoopFunction cannot pass function to task’s node, as seen in m.dataWithFunction.myFunction
which becomes Invalid. vice versa.
In order to call functions initialized by eventLoopFunction, we use m.port.
see m.top.observeField(“command”, m.port)
In order to pass data to eventLoopFunction, msg.GetData() and interface field, e.g. metadata, are used.

Download: http://riowing.net/p/DemoEventLoop.zip

Static function in BrightScript


There is no static keyword.
For example, myPoster is component name, which has a function called posterFunc, which is listed in interface section.
posterFunc can be called in two ways:

static way: posterFunc({calleePara: “calleeParaStaticMain”})
when not called from main.brs, e.g from MainScene.brs, MainScene.xml have to list myPoster.brs in script section.
myPoster.brs cannot have init() since init is to initialize object.
when called by main.brs, presence of init doesn’t cause error, but m.var = invalid referenced in posterFunc regardless init.

non-static way: poster.callFunc(“posterFunc”, {calleePara: “calleeParaNonStaticMainBeforeShow”})
no need to list myPoster.brs in .xml file
if called by main, poster = CreateObject(“roSGNode”, “myPoster”) has to be after screen.show()

Console output:
Main entered
CallFuncStaticWay calling posterFunc
myPoster::posterFunc passed in params= =
{
calleepara: "calleeParaStaticMain"
} , m.var=invalid
screen.show called
CallFuncNonStaticWay poster.callFunc-posterFunc
myPoster::posterFunc passed in params= =
{
calleepara: "calleeParaNonStaticMainBeforeShow"
} , m.var=mVarVal

Source code is here: http://riowing.net/p/AppNameStaticFunc.zip

Brightscript library called directly by firmware


It is obvious that main/runUserInterface in a channel, instead of library, is called by firmware.
How to make a function in library, instead of channel, that gets called without involving main/runUserInterface?
Here is a sample library to show how FW call BRS as it does with GrandCentral library.
Firmware loads roku_grandcentral_lib.zip, and calls launchContent.
On Brightscript side:
manifest file:
required: os_markup=1 sg_component_libs_provided=Roku_GrandCentral
sg_component_libs_provided so that FW knows it is a library instead of channel
optional: major_version, hidden=1
.xml file:
required: <field id=”scene” type=”node”/>
optional: base class of ContentLauncher, extends=”Node”, is not required
.brs:
required: the function being caalled by FW: launchContent
optional: init()
Folder structure and file name of xml and brs dont make difference.

On FW side:called in LaunchController.cpp

The way we know the function did get called:
check port 8085, and look for log message “Function launchContent is called by FW.”

BrightScript m variable


BrightScript is the language to program Roku streaming player.
The m keyword can be confusing.
code snippet from source/main.brs tagged with MvsThis, which stands for m vs this.

Function MvsThisCreate() as Object
	print "MvsThisCreate entered"
	obj = CreateObject("roAssociativeArray")
	obj.svc = "MvsThisSvc"
	obj.MvsThisFunc = MvsThisFunc
	obj.MvsThisFunc2 = MvsThisFunc2
	return obj
End Function

Function MvsThisFunc() as Void
	print "MvsThisFunc entered"
	print "MvsThisFunc m.svc="m.svc
	print "MvsThisFunc m.MvsThisFunc2="m.MvsThisFunc2
	print "MvsThisFunc MvsThisFunc2="MvsThisFunc2
	m.MvsThisFunc2("m.MvsThisFunc2")
	MvsThisFunc2("MvsThisFunc2")
End Function

Function MvsThisFunc2(str as String) as Void
	print "MvsThisFunc2 called by: "str
End Function

Function MvsThisTest() as Void
	print "MvsThisTest start"
	MvsThis = MvsThisCreate()
	MvsThis.MvsThisFunc()
	print "MvsThisTest done"
End Function

When we run MvsThisTest(), we get these output:

	MvsThisTest start
	MvsThisCreate entered
	MvsThisFunc entered
	MvsThisFunc m.svc=MvsThisSvc
	MvsThisFunc m.MvsThisFunc2=<Function: mvsthisfunc2>
	MvsThisFunc MvsThisFunc2=<Function: mvsthisfunc2>
	MvsThisFunc2 called by: m.MvsThisFunc2
	MvsThisFunc2 called by: MvsThisFunc2

As shown above, m is for accessing data in roAssociativeArray from roAssociativeArray’s function fields.
Calling m.MvsThisFunc2( and MvsThisFunc2(, without the m. are the same thing when the object is roAssociativeArray.
Calling m.MvsThisFunc2() doesn’t work if the object is SceneGraph node, e.g. loaded as xml file.