When i wrote the above SG "format" in B/S, i was trying to stay as close to XML as possible. So while better than XML, it's not exactly how a developer is inclined to write structures. But in my defense that format has a 1:1 mapping to XML, is non-ambiguous and i was planning of writing converter utility function, to build SG tree from it. Alas, the title "BrightScript/XML Markup Equivalence" i have seen turned out to be a ruse - there is no way (yet) to dynamically
declare a new component type or add/change functions to it.
Now,
if Roku's SG were properly supported by BrightScript, i should be able to do something like this instead (look ma, no xml!):
mg_ex = createObject("roSgNode", "Group")
mg_ex.createChild("MaskGroup", {id: "exampleMaskGroup",
maskuri: "pkg:/images/GradientLinear.png", masksize: [512, 288], maskOffset: [0, 0]
children: [
createObject("roSgNode", "Poster", {uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288})
]
})
mga = createObject("roSgNode", "Animation", {id: "MaskGroupAnimation",
duration: 3, easeFunction: "linear", repeat: true
children: [
createObject("roSgNode", "Vector2DFieldInterpolator", {id: "interpolator",
fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]]
})
]
})
mg_ex.appendChild(mga)
mga.control = "start"
Much better but still tad tedious, since there is
createObject() within
createObject() or the use temp variables. But notice how "the need" to sub-class and write an initializer vanished naturally.
We can do better too, describe the object like so:
MaskGroupExample = { type: "Group"
init: function()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end function
children: [
{ type: "MaskGroup", id: "exampleMaskGroup",
maskuri: "pkg:/images/GradientLinear.png", masksize: [512, 288], maskOffset: [0, 0]
children: [
{ type: "Poster", uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288}
]
}
{ type: "Animation", id: "MaskGroupAnimation",
duration: 3, easeFunction: "linear", repeat: true
children: [
{ type: "Vector2DFieldInterpolator", id: "interpolator",
fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]]
}
]
}
]
}
So that's ust a roAA, what do we do with it? Well, in a perfect world i should be able to create the node by calling
mg_ex = createObject("roSgNode", MaskGroupExample)
i.e. passing roAA as argument (instead of string) would be walked by the sgNode constructor, creating all nested nodes. In the mean time though - till the cows come home - it's trivial for us to write own B/S utility function that does the same by walking the tree and createObject() the nested levels.