Skip to content

Commit

Permalink
Merge pull request #119 from triwav/add_support_for_sceneSubBoundingRect
Browse files Browse the repository at this point in the history
add support for sceneSubBoundingRect and other functions requiring params, fix failing test on 12.5
  • Loading branch information
triwav authored Nov 17, 2023
2 parents 9f9d1d3 + 6c2ba34 commit 9d182bc
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 22 deletions.
29 changes: 22 additions & 7 deletions client/src/OnDeviceComponent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -742,24 +742,24 @@ describe('OnDeviceComponent', function () {
backExitsScene: 'boolean',
backgroundColor: 'color',
backgroundUri: 'uri',
change: 'string',
childRenderOrder: 'string',
change: 'std::type_index',
childRenderOrder: 'std::type_index',
clippingRect: 'rect2d',
currentDesignResolution: 'std::shared_ptr<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::any, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::any> > > >',
dialog: 'std::shared_ptr<Roku::SceneGraph::DialogBase>',
currentDesignResolution: 'std::type_index',
dialog: 'std::type_index',
enableRenderTracking: 'boolean',
focusable: 'boolean',
focusedChild: 'node',
focusedChild: 'std::type_index',
id: 'string',
inheritParentOpacity: 'boolean',
inheritParentTransform: 'boolean',
limitBackgroundToUIResolution: 'boolean',
muteAudioGuide: 'boolean',
opacity: 'float',
pagesContainer: 'node',
palette: 'std::shared_ptr<Roku::SceneGraph::RSGPalette>',
palette: 'std::type_index',
renderPass: 'integer',
renderTracking: 'string',
renderTracking: 'std::type_index',
rotation: 'float',
scale: 'vector2d',
scaleRotateCenter: 'vector2d',
Expand Down Expand Up @@ -834,6 +834,21 @@ describe('OnDeviceComponent', function () {
expect(found).to.false;
});
});

describe('sceneSubBoundingRect()', () => {
it('should work on node item', async () => {
const { value } = await odc.getValue({ keyPath: '#rowListWithCustomTitleComponent.sceneSubBoundingRect(item1_1)' });
expect(value.height).to.equal(150);
expect(value.width).to.equal(300);
expect(value.x).to.equal(480);
expect(value.y).to.equal(936);
});

it('should gracefully fallback if called on nonsupported type', async () => {
const { found } = await odc.getValue({ base: 'global', keyPath: 'intValue.sceneSubBoundingRect(item0_1)()' });
expect(found).to.false;
});
});
});
});

Expand Down
47 changes: 32 additions & 15 deletions device/components/RTA_helpers.brs
Original file line number Diff line number Diff line change
Expand Up @@ -321,75 +321,91 @@ end function
' * @description Helper for RTA_getValueAtKeyPath to break out
' * @param {Object} key - Key of the function the user is asking us to call
' * @param {Dynamic} level - The variable we are calling the function call on
' * @param {Integer} openingParenthesisPosition - Where the opening paranthesis are located in keyPathPart
' */
function RTA_callBrightscriptInterfaceFunction(functionName as string, callOn as Dynamic) as Dynamic
if functionName = "getParent()" then
function RTA_callBrightscriptInterfaceFunction(keyPathPart as string, callOn as Dynamic, openingParenthesisPosition as Integer) as Dynamic
functionName = left(keyPathPart, openingParenthesisPosition)
closingParenthesisPosition = keyPathPart.len()
if mid(keyPathPart, closingParenthesisPosition) <> ")" then
RTA_logWarn("Could not find closing parenthesis" + keyPathPart)
return Invalid
end if
numCharacters = closingParenthesisPosition - (openingParenthesisPosition + 2)
functionParams = mid(keyPathPart, openingParenthesisPosition + 2, numCharacters).tokenize(",")

if functionName = "getParent" then
if RTA_isNode(callOn) then
return callOn.getParent()
else
RTA_logWarn("tried to call getParent() on non node of type " + type(callOn))
end if
else if functionName = "count()" then
else if functionName = "count" then
if RTA_isArray(callOn) OR RTA_isKeyedValueType(callOn) then
return callOn.count()
else
RTA_logWarn("tried to call count() on non AA or array of type " + type(callOn))
end if
else if functionName = "keys()" then
else if functionName = "keys" then
if RTA_isNode(callOn) then
return callOn.keys().toArray() ' keys() returns an roList when called on a node. We have to convert to array as all of our array checks are specifically looking for an array
else if RTA_isAA(callOn) then
return callOn.keys()
else
RTA_logWarn("tried to call keys() on non keyed value of type " + type(callOn))
end if
else if functionName = "len()" then
else if functionName = "len" then
if RTA_isString(callOn) then
return callOn.len()
else
RTA_logWarn("tried to call len() on non string of type " + type(callOn))
end if
else if functionName = "getChildCount()" then
else if functionName = "getChildCount" then
if RTA_isNode(callOn) then
return callOn.getChildCount()
else
RTA_logWarn("tried to call getChildCount() on non node of type " + type(callOn))
end if
else if functionName = "threadinfo()" then
else if functionName = "threadinfo" then
if RTA_isNode(callOn) then
return callOn.threadinfo()
else
RTA_logWarn("tried to call threadinfo() on non node of type " + type(callOn))
end if
else if functionName = "getFieldTypes()" then
else if functionName = "getFieldTypes" then
if RTA_isNode(callOn) then
return callOn.getFieldTypes()
else
RTA_logWarn("tried to call getFieldTypes() on non node of type " + type(callOn))
end if
else if functionName = "subtype()" then
else if functionName = "subtype" then
if RTA_isNode(callOn) then
return callOn.subtype()
else
RTA_logWarn("tried to call subtype() on non node of type " + type(callOn))
end if
else if functionName = "boundingRect()" then
else if functionName = "boundingRect" then
if RTA_isNode(callOn) then
return callOn.boundingRect()
else
RTA_logWarn("tried to call boundingRect() on non node of type " + type(callOn))
end if
else if functionName = "localBoundingRect()" then
else if functionName = "localBoundingRect" then
if RTA_isNode(callOn) then
return callOn.localBoundingRect()
else
RTA_logWarn("tried to call localBoundingRect() on non node of type " + type(callOn))
end if
else if functionName = "sceneBoundingRect()" then
else if functionName = "sceneBoundingRect" then
if RTA_isNode(callOn) then
return callOn.sceneBoundingRect()
else
RTA_logWarn("tried to call sceneBoundingRect() on non node of type " + type(callOn))
RTA_logWarn("tried to call sceneBoundingRect on non node of type " + type(callOn))
end if
else if functionName = "sceneSubBoundingRect" then
if RTA_isNode(callOn) then
return callOn.sceneSubBoundingRect(functionParams[0])
else
RTA_logWarn("tried to call sceneBoundingRect on non node of type " + type(callOn))
end if
else
RTA_logWarn("tried to call unknown function" + functionName)
Expand All @@ -416,8 +432,9 @@ function RTA_getValueAtKeyPath(base as Object, keyPath as String, fallback = Inv
while NOT keys.isEmpty()
key = keys.shift()
' Check for any Brightscript interface function calls
if key.Instr("()") > 0 then
level = RTA_callBrightscriptInterfaceFunction(key, level)
openingParenthesisPosition = key.Instr("(")
if openingParenthesisPosition > 0 then
level = RTA_callBrightscriptInterfaceFunction(key, level, openingParenthesisPosition)
else if RTA_isKeyedValueType(level) then
nextLevel = level[key]
if nextLevel = Invalid AND RTA_isNode(level) then
Expand Down

0 comments on commit 9d182bc

Please sign in to comment.