diff --git a/test-project/.vscode/launch.json b/test-project/.vscode/launch.json
deleted file mode 100644
index 6c6b34e..0000000
--- a/test-project/.vscode/launch.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "version": "0.2.0",
- "configurations": [
- {
- "type": "brightscript",
- "request": "launch",
- "name": "run",
- "stopOnEntry": false,
- "host": "192.168.8.169",
- "password": "aaaa"
- }
- ]
-}
\ No newline at end of file
diff --git a/test-project/.vscode/settings.json b/test-project/.vscode/settings.json
deleted file mode 100644
index 9fb416f..0000000
--- a/test-project/.vscode/settings.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "files.exclude": {
- "node_modules": true,
- "out": true
- }
-}
\ No newline at end of file
diff --git a/test-project/components/MainScene.brs b/test-project/components/MainScene.brs
deleted file mode 100644
index b093842..0000000
--- a/test-project/components/MainScene.brs
+++ /dev/null
@@ -1,106 +0,0 @@
-function init() as void
- createObject("roSGNode", "TrackerTask")
- m.top.observeField("fire", "onTimerFire")
-
- m.textIndex = 0
- m.label = m.top.findNode("label")
- configureLabel()
- makeTexts()
- m.label.text = m.texts[0]
-end function
-
-function makeTexts()
- text0 = "\n#TITLE1:#"
- text0 += "\n##TITLE2:##"
- text0 += "\n###TITLE3:###"
- text0 += "\n*bold text here*"
- text0 += "\n_italic text here_"
- text0 += "\nregular text"
- text0 += "\nposter 1 ${so1} poster 2 ${so2} poster 3 ${so3}"
-
- text1 = "#Video ${name}#"
- text1 += "\n##Description:##"
- text1 += "\n###${description}###"
- text1 += "\n\n_runningtime_: *${time}* _rating_: *${rating}*"
- text1 += "\nhere is some more text"
- text1 += "\nposter ${so1} test here ${so2} more text"
- text1 += "\n${so3}"
-
- text2 = "\n\n#you shoudl watch ${name}#"
- text2 += "\n${so3}"
- text2 += "\n##Description:##"
- text2 += "\n###${description}###"
- text2 += "\n\n*runningtime*: ${time} *rating*: ${rating}"
- text2 += "\nhere is some more text *with bold* normal *italic*"
- text2 += "\nposter ${so1} test here ${so2} more text"
-
- text3 = "\n#TITLE1:#"
- text3 += "\n##TITLE2:##"
- text3 += "\n###TITLE3:###"
- text3 += "\nposter ${so1} test here ${so2} more text"
-
- m.texts = [
- text0
- text1
- text2
- text3
- ]
-end function
-
-
-function onTimerFire()
- m.textIndex++
- if m.textIndex = m.texts.count()
- m.textIndex = 0
- end if
-
- m.label.text = m.texts[m.textIndex]
-end function
-
-
-function configureLabel()
- m.label.allFontSettings = {
- header1Font: {
- name: "font:MediumBoldSystemFont"
- size: 130
- }
- header2Font: {
- name: "font:MediumBoldSystemFont"
- size: 60
- }
- header3Font: {
- name: "font:MediumSystemFont"
- size: 50
- }
- font: {
- name: "font:MediumSystemFont"
- size: 30
- }
- italicFont: {
- name: "font:MediumBoldSystemFont"
- size: 32
- }
- boldFont: {
- name: "font:MediumSystemFont"
- size: 34
- } }
-
- m.label.values = {
- name: "Jurassic Park"
- description: "Dinosaur antics and jolly good fun"
- time: "1h30m"
- icon: "https:"
- rating: "pg"
- so1: makePoster("so1.png")
- so2: makePoster("so2.png")
- so3: makePoster("so3.png")
- }
-end function
-
-function makePoster(name)
- poster = createObject("roSGNode", "Poster")
- poster.width = 40
- poster.height = 40
- poster.uri = "pkg:/images/" + name
- return poster
-end function
diff --git a/test-project/components/MainScene.xml b/test-project/components/MainScene.xml
deleted file mode 100644
index 6ceff6f..0000000
--- a/test-project/components/MainScene.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test-project/components/RALETRackerTask.brs b/test-project/components/RALETRackerTask.brs
deleted file mode 100644
index 6e691fa..0000000
--- a/test-project/components/RALETRackerTask.brs
+++ /dev/null
@@ -1,2691 +0,0 @@
-' RALE_Config - RALE config singleton class
-' @return {object} - RALE config properties
-Function RALE_Config() as Object
- if m.appConfig = Invalid then m.appConfig = RALE_InitConfig()
- return m.appConfig
-End Function
-
-' RALE_InitConfig - RALE config init function. Defines all config properties
-' @return {object} - RALE config properties
-Function RALE_InitConfig() as Object
- this = {
- bufferSize: 100024,
- minSocketPort: 49152,
- maxSocketPort: 65535,
- screensaverResetTimeout: 30000,
- commandTimeout: 10000,
- defaultLogLevel: 3,
- logFormat: "[RALE][%level%] - %message%"
- }
-
- return this
-End Function
-
-
-' RALE_Logger - Constructor of Logger class
-' @param {integer} level - log verbosity level (0-4)
-' @param {string} format - log message format ("[MY_CUSTOM_PREFIX]%message%")
-' @return {object} - logger instance
-function RALE_Logger(level = -1 as Integer, format = "%message%" as String) as Object
- this = {}
-
- this.verbosityList = ["OFF", "ERROR", "WARN", "INFO", "DEBUG"]
- this.verbosityMap = {
- off : 0
- error : 1
- warning : 2
- info : 3
- debug : 4
- }
- this.formatMethods = {
- date: "getDate",
- time: "getTime",
- level: "getLevel",
- message: "getMessage"
- }
-
- this.dt = createObject("roDateTime")
-
- this.setVerbosity = RALE_Logger__SetVerbosityLevel
- this.setFormat = RALE_Logger__SetFormat
-
- this.getDate = RALE_Logger__GetDate
- this.getTime = RALE_Logger__GetTime
- this.getLevel = RALE_Logger__GetLevel
- this.getMessage = RALE_Logger__GetMessage
-
- this.debug = RALE_Logger__DebugLog
- this.info = RALE_Logger__InfoLog
- this.warning = RALE_Logger__WarningLog
- this.error = RALE_Logger__ErrorLog
- this.logMessage = RALE_Logger__LogMessage
-
- this.setVerbosity(level)
- this.setFormat(format)
-
- return this
-end function
-
-' RALE_Logger__SetVerbosityLevel - change logger verbosity level
-' @param {integer} level - log verbosity level (0-4)
-sub RALE_Logger__SetVerbosityLevel(level = 4 as Integer)
- if level > m.verbosityMap.debug then
- m.verbosityLevel = m.verbosityMap.debug
- else if level < m.verbosityMap.off then
- m.verbosityLevel = m.verbosityMap.off
- else
- m.verbosityLevel = level
- end if
-end sub
-
-' RALE_Logger__SetFormat - Change logger message format
-' @param {string} format - log message format ("[MY_CUSTOM_PREFIX]%message%")
-' Available format variables:
-' %message% - message with which the log function is called (at the end by default)
-' %date% - current date in format "[year]-[month]-[day]"
-' %time% - current time in format "[hours]:[minutes]:[seconds].[miliseconds]"
-' %level% - verbosity level ("ERROR", "WARN", "INFO" or "DEBUG")
-sub RALE_Logger__SetFormat(format = "%message%" as String)
- if Instr(1, format, "%message%") = 0 then
- format = format + "%message%"
- end if
- m.formatList = format.split("%")
-end sub
-
-'==========================================
-' Wrappers over various levels of logging
-'==========================================
-
-' RALE_Logger__DebugLog - Log message into console with DEBUG verbosity level
-' @param {string} message - log message
-sub RALE_Logger__DebugLog(message = "")
- m.logMessage(message, m.verbosityMap.debug)
-end sub
-
-' RALE_Logger__InfoLog - Log message into console with INFO verbosity level
-' @param {string} message - log message
-sub RALE_Logger__InfoLog(message = "")
- m.logMessage(message, m.verbosityMap.info)
-end sub
-
-' RALE_Logger__WarningLog - Log message into console with WARNING verbosity level
-' @param {string} message - log message
-sub RALE_Logger__WarningLog(message = "")
- m.logMessage(message, m.verbosityMap.warning)
-end sub
-
-' RALE_Logger__ErrorLog - Log message into console with ERROR verbosity level
-' @param {string} message - log message
-sub RALE_Logger__ErrorLog(message)
- m.logMessage(message, m.verbosityMap.error)
-end sub
-
-'==========================================
-' Main log function
-'==========================================
-
-' RALE_Logger__LogMessage - Log message into console by message format if logLevel is more than current verbosityLevel
-' @param {string} message - log message
-' @param {integer} logLevel - log verbosity level (0-4)
-sub RALE_Logger__LogMessage(message as String, logLevel as Integer)
- if logLevel > 0 and m.verbosityLevel >= logLevel then
- logMessage = ""
-
- for each item in m.formatList
- formatMethod = m.formatMethods[item]
-
- if formatMethod = Invalid then
- logMessage = logMessage + item
- else
- logMessage = logMessage + m[formatMethod](message, logLevel)
- end If
- end for
-
- print logMessage
- end if
-end sub
-
-'==========================================
-' Utitlity functions
-'==========================================
-
-' RALE_Logger__GetTime - Returns current time
-' @param {string} message - log message
-' @return {string} - current time in format: "[hours]:[minutes]:[seconds].[miliseconds]"
-function RALE_Logger__GetTime(message as String, level as Integer)
- m.dt.Mark()
-
- h = RALE_Logger__getZeroNumber(m.dt.getHours())
- n = RALE_Logger__getZeroNumber(m.dt.getMinutes())
- s = RALE_Logger__getZeroNumber(m.dt.getSeconds())
- ms = str(m.dt.getMilliseconds()).trim()
- if len(ms) = 1
- ms = ms + "0"
- else
- ms = left(ms, 2)
- end if
- return h + ":" + n + ":" + s + "." + ms
-end function
-
-' RALE_Logger__GetDate - Returns current date
-' @param {string} message - log message
-' @return {string} - current date in format: "[year]-[month]-[day]"
-function RALE_Logger__GetDate(message as String, level as Integer)
- m.dt.Mark()
- y = str(m.dt.getYear()).trim()
- mm = RALE_Logger__getZeroNumber(m.dt.getMonth())
- d = RALE_Logger__getZeroNumber(m.dt.getDayOfMonth())
- return y + "-" + mm + "-" + d
-end function
-
-' RALE_Logger__GetLevel - Returns current verbosity level
-' @param {string} message - log message
-' @return {integer} - verbosity level
-function RALE_Logger__GetLevel(message as String, level as Integer)
- return m.verbosityList[level]
-end function
-
-' RALE_Logger__GetMessage - Returns log message (needed for formating log message)
-' @param {string} message - log message
-' @return {string} - log message
-function RALE_Logger__GetMessage(message as String, level as Integer)
- return message
-end function
-
-' RALE_Logger__getZeroNumber - Convert number to format "0[number]" if it has less then 2 digits
-' @param {number} n - number for converting
-' @param {number} to_length - the necessary count of digits
-' @return {string} - converted number format
-function RALE_Logger__getZeroNumber(n, to_length=2)
- n = str(n).trim()
- if len(n) < to_length
- n = String(to_length - 1, "0") + n
- end if
- return n
-end function
-
-
-' CreateRedLines - Selector (live) view class constructor
-' @return {object} - selector (live) view
-Function CreateRedLines() as Object
- this = {}
- node = CreateObject("roSGNode", "Group")
- node.addFields({"isExternallyExposed": true})
- this.node = node
- this.childMap = {}
-
- this.setLine = RedLines_SetLine
- this.setRulerLines = RedLines_SetRulerLines
- this.removeLine = RedLines_RemoveLine
- this.removeAllLines = RedLines_RemoveAllLines
-
- this.resolution = m.top.getScene().getField("currentDesignResolution")
-
- return this
-End Function
-
-Sub RedLines_SetLine(id, position, coords)
- if (m.childMap[id] = invalid) then
- RedLines_AddLine(id, position, coords, m.node, m.childMap)
- else
- RedLines_UpdatePosition(id, coords, m.childMap)
- end if
-end Sub
-
-Sub RedLines_SetRulerLines(rulerLines)
- For Each line In rulerLines.Items()
- RedLines_AddLine(line.key, line.value.position, line.value.coords, m.node, m.childMap)
- End For
-end Sub
-
-Sub RedLines_AddLine(id, position, coords, node, childMap) as Object
- line = CreateObject("roSGNode", "Rectangle")
- line.setField("id", id)
- line.setField("color", "#00F8FF")
- line.addFields({"position": position})
- RedLines_SetLineCoords(line, coords)
- node.appendChild(line)
- childMap[id] = line
-end Sub
-
-Sub RedLines_UpdatePosition(id, coords, childMap) as Object
- line = childMap[id]
- RedLines_SetLineCoords(line, coords)
-end Sub
-
-Sub RedLines_SetLineCoords(node, coords) as Integer
- if node.position = "horizontal" then
- node.setField("translation", [coords.x,0])
- node.setField("width", 1)
- node.setField("height", m.resolution.height)
- end if
- if node.position = "vertical" then
- node.setField("translation", [0,coords.y])
- node.setField("width", m.resolution.width)
- node.setField("height", 1)
- end if
-end Sub
-
-Sub RedLines_RemoveLine(id)
- line = m.childMap[id]
- m.node.removeChild(line)
- m.childMap[id] = invalid
-end Sub
-
-Sub RedLines_RemoveAllLines()
- childrenList = m.node.getChildren(-1,0)
- m.node.removeChildren(childrenList)
- m.childMap = {}
-end Sub
-
-
-' CreateSelectorView - Selector (live) view class constructor
-' @return {object} - selector (live) view
-Function CreateSelectorView() as Object
- view = CreateObject("roSGNode", "Group")
-
- m.resolution = m.top.getScene().getField("currentDesignResolution")
- m.resWidth = m.resolution.width
- m.resHeight = m.resolution.height
-
- children = [
- {subtype : "Rectangle", fields : {id : "l"}}
- {subtype : "Rectangle", fields : {id : "r"}}
- {subtype : "Rectangle", fields : {id : "b"}}
- {subtype : "Rectangle", fields : {id : "t"}}
-
- {subtype : "Rectangle", fields : {id : "horiz"}}
- {subtype : "Rectangle", fields : {id : "vert"}}
-
-
- {subtype : "Rectangle", fields : {id : "leftLine"}}
- {subtype : "Rectangle", fields : {id : "topLine"}}
- {subtype : "Rectangle", fields : {id : "rightLine"}}
- {subtype : "Rectangle", fields : {id : "bottomLine"}}
-
- {subtype : "Label", fields : {id : "leftCords"}}
- {subtype : "Label", fields : {id : "topCords"}}
- {subtype : "Label", fields : {id : "rightCords"}}
- {subtype : "Label", fields : {id : "bottomCords"}}
-
- {subtype : "Rectangle", fields : {id : "fill", color : "#ffffff44"}}
- {subtype : "Timer", fields : {id : "timer", duration : 1 / 60, repeat : true}}
- ]
-
- viewObject = NodeUtils_AddChildrenToNode(view, children)
- childrenMap = {}
- for each child in viewObject.children
- node = child.node
- childrenMap[node.id] = node
- end for
-
- interface = [
- {id:"width", type:"float", value : "1280", onChange : "SelectorView_UpdateView"}
- {id:"height", type:"float", value : "40", onChange : "SelectorView_UpdateView"}
- {id:"border", type:"float", value : "2", onChange : "SelectorView_UpdateView"}
- {id:"oldBoundingRect", type:"assocarray" }
- {id:"boundingRect", type:"assocarray", onChange : "SelectorView_UpdateViewFromBRect"}
- {id:"color", type:"color", value : "#FFFFFF", onChange : "SelectorView_UpdateColors"}
- {id:"attachedView", type:"node", onChange : "SelectorView_AttachToView"}
- {id:"isExternallyExposed", type:"boolean", value : "true"}
- {id:"childrenMap", type:"assocarray", value : childrenMap}
- ]
- NodeUtils_AddInterfaceToNode(view, interface)
-
- timer = view.childrenMap.timer
- timer.observeField("fire","SelectorView_UpdateViewPosition")
- timer.control = "start"
-
- return view
-End Function
-
-' NodeUtils_AddInterfaceToNode - Adds interface to node
-' @param {object} node - node
-' @param {object} interface - interface
-' @return {boolean} - is interface was added
-Function NodeUtils_AddInterfaceToNode(node, interface as Object) as Boolean
- if node = invalid OR interface = invalid then return false
- for each field in interface
- NodeUtils_AddNodeInterfaceField(node, field)
- end for
- return true
-End Function
-
-' NodeUtils_AddNodeInterfaceField - Adds interface field to node
-' @param {object} node - node
-' @param {object} fieldConfig - field config
-' @return {boolean} - is interface was added
-Function NodeUtils_AddNodeInterfaceField(node, fieldConfig as Object) as Boolean
- if node = invalid OR fieldConfig = invalid then return false
- if fieldConfig.id = invalid then return false
- if fieldConfig.type = invalid then return false
-
- if fieldConfig.alwaysNotify = invalid then fieldConfig.alwaysNotify = true
-
- if node.hasField(fieldConfig.id) then return false
-
- node.addField(fieldConfig.id, fieldConfig.type, fieldConfig.alwaysNotify)
-
- if not node.hasField(fieldConfig.id) then return false
-
- if fieldConfig.value <> invalid then
- node[fieldConfig.id] = fieldConfig.value
- end if
-
- if fieldConfig.onChange <> invalid then
- node.observeField(fieldConfig.id, fieldConfig.onChange)
- end if
-
- return true
-End Function
-
-' NodeUtils_AddChildrenToNode - Adds children to node
-' @param {object} node - node
-' @param {object} childrenConfig - children config
-' @return {object} - view object
-Function NodeUtils_AddChildrenToNode(node, childrenConfig as Object) as Object
- if node = invalid then return invalid
- viewObject = {node : node, children : []}
- if childrenConfig <> invalid then
- for each childConfig in childrenConfig
- childObject = NodeUtils_AddChildToNode(node, childConfig)
- viewObject.children.push(childObject)
- end for
- end if
-
- return viewObject
-End Function
-
-' NodeUtils_AddChildToNode - Adds child to node
-' @param {object} node - node
-' @param {object} childConfig - child config
-' @return {object} - view object
-Function NodeUtils_AddChildToNode(node, childConfig) as Object
- if node = invalid or childConfig = invalid then return invalid
- if childConfig.subtype = invalid then return invalid
- view = node.CreateChild(childConfig.subtype)
- if view = invalid then return invalid
- if childConfig.fields <> invalid then view.setFields(childConfig.fields)
- return NodeUtils_AddChildrenToNode(view, childConfig.children)
-End Function
-
-' NumberToFixed - formats a number using fixed-point notation
-' @param {float, double} number - formated number
-' @param {integer} digits - the number of digits to appear after the decimal point
-' @return {string} - a string representing the given number using fixed-point notation
-Function NumberToFixed(number, digits) as String
- str = number.toStr()
- arr = str.split(".")
-
- if arr.count() > 1 and digits > 0 then
- return arr[0] + "." + Left(arr[1], digits)
- end if
-
- return arr[0]
-End Function
-
-' SelectorView_UpdateView - width, height and border change event handler. Updates Selector (live) view
-' @param {object} event - event data
-Sub SelectorView_UpdateView(event)
- node = event.getRoSGNode()
- border = node.border
- width = node.width
- height = node.height
- x = node.boundingRect.x
- y = node.boundingRect.y
- rightPos = x + width + border*2
- bottomPos = y + height + border*2
-
- l = node.childrenMap.l
- l.width = border
- l.height = height + border*2
- l.translation = [-border, -border]
-
- r = node.childrenMap.r
- r.width = border
- r.height = height + border*2
- r.translation = [width, -border]
-
- t = node.childrenMap.t
- t.width = width + border*2
- t.height = border
- t.translation = [-border, -border]
-
- b = node.childrenMap.b
- b.width = width + border*2
- b.height = border
- b.translation = [-border, height]
-
- horiz = node.childrenMap.horiz
- horiz.width = width
- horiz.height = border
- horiz.translation = [0, (height - border) / 2]
-
- vert = node.childrenMap.vert
- vert.width = border
- vert.height = height
- vert.translation = [(width - border) / 2, 0]
-
- leftLine = node.childrenMap.leftLine
- leftLine.width = x
- leftLine.height = border
- leftLine.translation = [-x, (height - border) / 2]
-
- topLine = node.childrenMap.topLine
- topLine.width = border
- topLine.height = y
- topLine.translation = [(width - border) / 2, -y]
-
- rightLine = node.childrenMap.rightLine
- rightLine.width = m.resWidth - x + 10
- rightLine.height = border
- rightLine.translation = [width + border, (height - border) / 2]
-
- bottomLine = node.childrenMap.bottomLine
- bottomLine.width = border
- bottomLine.height = m.resHeight - y + 10
- bottomLine.translation = [(width - border) / 2, height + border]
-
- leftCords = node.childrenMap.leftCords
- leftCords.font.size = 20
- leftCords.color = "#FF0000"
- leftCords.text = NumberToFixed(x, 0)
- leftCords.translation = [-x/2 - 10, (height - border) / 2 - 20]
-
- topCords = node.childrenMap.topCords
- topCords.font.size = 20
- topCords.color = "#FF0000"
- topCords.text = NumberToFixed(y, 0)
- topCords.translation = [(width - border) / 2 + 10, -y/2 - 10]
-
- rightCords = node.childrenMap.rightCords
- rightCords.font.size = 20
- rightCords.color = "#FF0000"
- rightCords.text = NumberToFixed(m.resWidth - x - width, 0)
- rightCords.translation = [width + (m.resWidth - rightPos)/2 - 5, (height - border) / 2 - 20]
-
- bottomCords = node.childrenMap.bottomCords
- bottomCords.font.size = 20
- bottomCords.color = "#FF0000"
- bottomCords.text = NumberToFixed(m.resHeight - y - height, 0)
- bottomCords.translation = [(width - border) / 2 + 10, height + (m.resHeight - bottomPos)/2 - 5]
-
- fill = node.childrenMap.fill
- fill.width = width
- fill.height = height
-End Sub
-
-' SelectorView_UpdateColors - color change event handler. Updates Selector (live) view color
-' @param {object} event - event data
-Sub SelectorView_UpdateColors(event)
- node = event.getRoSGNode()
- for each view in node.getchildren(-1,0)
- if view.isSubtype("Rectangle") and view.id <> "fill" then view.color = node.color
- end for
-End Sub
-
-' SelectorView_UpdateViewFromBRect - boundingRect change event handler.
-' Updates Selector (live) view translation, width and height
-' @param {object} event - event data
-Sub SelectorView_UpdateViewFromBRect(event)
- node = event.getRoSGNode()
- boundingRect = node.boundingRect
- if boundingRect <> Invalid then
- node.setFields({
- translation : [boundingRect.x, boundingRect.y]
- width : boundingRect.width
- height : boundingRect.height
- })
- end if
-End Sub
-
-' isBoundingRectChanged - checks is bounding rect was changed
-' @param {object} br - node bounding rect
-' @param {object} node - node
-' @return {boolean} - true if node bounding rect was changed
-Sub isBoundingRectChanged(br, node) as Boolean
- o = node.oldBoundingRect
- if o = Invalid then
- node.oldBoundingRect = br
- return true
- end if
- if o.x = br.x and o.y = br.y and o.width = br.width and o.height = br.height then
- return false
- else
- node.oldBoundingRect = br
- return true
- end if
-End Sub
-
-' SelectorView_UpdateViewPosition - interval event handler. Updates selector (live) view position
-' @param {object} event - node bounding rect
-Sub SelectorView_UpdateViewPosition(event)
- timer = event.getRoSGNode()
- node = timer.getparent()
-
- if node.attachedView <> Invalid then
- boundingRect = node.attachedView.sceneboundingRect()
- else
- boundingRect = {x: -100, y: -100, width: 0, height: 0}
- end if
-
- if isBoundingRectChanged(boundingRect, node) then
- node.boundingRect = boundingRect
- end if
-End Sub
-
-
-' getCommandMap - Defines map that contains all RALE commands handlers
-' @return {object} - handlers map
-Sub getCommandMap() as Object
- return {
- "init" : "UIThread_init",
-
- ' Config commands
- "showSelectorView" : "UIThread_showSelectorView",
- "hideSelectorView" : "UIThread_hideSelectorView",
-
- ' Node commands
- "selectNode" : "UIThread_selectNode",
- "updateNode" : "UIThread_updateNode",
- "getNodeData" : "UIThread_getNodeData",
-
- ' Tree View commands
- "getItemList" : "UIThread_getItemList",
- "getNodeTree" : "UIThread_getNodeTree",
- "getNodeById" : "UIThread_getNodeById",
- "getNodeByName" : "UIThread_getNodeByName",
-
- ' Children commands
- "addChild" : "UIThread_addChild",
- "removeChild" : "UIThread_removeChild",
- "moveChild" : "UIThread_moveChild",
-
- ' Field commands
- "setField" : "UIThread_setField",
- "removeField" : "UIThread_removeField",
-
- ' Focus commands
- "setFocus" : "UIThread_setFocus",
- "selectFocusedNode" : "UIThread_selectFocusedNode",
-
- ' Bounding Rect commands
- "setBoundingRect" : "UIThread_setBoundingRect",
-
- ' Registry commands
- "getRegistrySections" : "UIThread_getRegistrySections",
- "clearRegistry" : "UIThread_clearRegistry",
- "addRegistrySection" : "UIThread_addRegistrySection",
- "removeRegistrySection" : "UIThread_removeRegistrySection",
- "addRegistryField" : "UIThread_addRegistryField",
- "removeRegistryField" : "UIThread_removeRegistryField",
- "editRegistryField" : "UIThread_editRegistryField",
-
- ' Logger commands
- "setLogVerbosity" : "UIThread_setLogVerbosity",
- "setLogFormat" : "UIThread_setLogFormat",
- "log" : "UIThread_log"
-
- ' Ruler lines commands
- "setRulerLine" : "UIThread_setRulerLine",
- "setRulerLines" : "UIThread_setRulerLines",
- "removeRulerLine" : "UIThread_removeRulerLine",
- "removeAllRulerLines" : "UIThread_removeAllRulerLines",
- }
-End Sub
-
-' callCommand - Call RALE command functuin from UI thread
-' @param {string} command - command name
-' @param {object} args - command arguments
-' @return {object} - response of RALE command
-Sub callCommand(command, args) as Object
- return m.top.callFunc(command, args)
-End Sub
-
-' UIThread_init - RALE "init" command
-' @param {object} args - command arguments
-' @return {object} - response of command. Contains RALE version and session id
-Sub UIThread_init(args) as Object
- root = m.top.GetScene()
-
- m.currentNode = root
- m.currentPath = []
-
- if m.selectorView = Invalid then
- m.selectorView = CreateSelectorView()
- m.selectorView.color = "#ff0000"
- m.selectorView.opacity = 0.6
- m.showSelectorView = true
- root.appendChild(m.selectorView)
- end if
-
- if m.redLines = Invalid then
- m.redLines = CreateRedLines()
- root.appendChild(m.redLines.node)
- else
- UIThread_removeAllRulerLines({})
- end if
-
- if args.logVerbosity >= 0 then
- UIThread_setLogVerbosity({ level: args.logVerbosity })
- end if
-
- if FW_IsString(args.logFormat) then
- UIThread_setLogFormat({ format: args.logFormat })
- end if
-
- m.logger.info("RALE Initialized")
- return { raleVersion: m.raleVersion, sessionid: m.sessionId }
-End Sub
-
-'=======================
-' Config commands
-'=======================
-
-' UIThread_showSelectorView - RALE "showSelectorView" command handler. Shows Selector (Live) View
-' @param {object} args - command arguments
-Sub UIThread_showSelectorView(args) as Object
- m.showSelectorView = true
- setSelectorView(m.currentNode, type(m.currentNode), m.currentPath)
- m.logger.debug("Selector View was disabled")
-End Sub
-
-' UIThread_hideSelectorView - RALE "hideSelectorView" command handler. Hides Selector (Live) View
-' @param {object} args - command arguments
-Sub UIThread_hideSelectorView(args) as Object
- m.showSelectorView = false
- setSelectorView(m.currentNode, type(m.currentNode), m.currentPath)
- m.logger.debug("Selector View was enabled")
-End Sub
-
-'=======================
-' Node commands
-'=======================
-
-' UIThread_selectNode - RALE "selectNode" command handler. Selects node by path
-' @param {object} args - command arguments
-' @return {object} - response of command. Contains node path and node data (id, type, fields, layout etc.)
-Sub UIThread_selectNode(args) as Object
- path = args["path"]
-
- root = m.top.getScene()
- node = RALE_getNodeByPath(root, path)
- if node = Invalid then return getError("Invalid Path")
-
- nodeType = type(node)
-
- if nodeType <> "roSGNode" and nodeType = "roArray" and nodeType = "roAssociativeArray" then
- return getError("Invalid Node Type")
- end if
-
- if nodeType = "roSGNode" and node.isExternallyExposed <> Invalid then
- return getError("Node Is Externally Exposed")
- end if
-
- if nodeType <> "roSGNode" or not node.IsSameNode(m.currentNode) then
- m.currentPath = path
- m.currentNode = node
- end if
-
- setSelectorView(node, nodeType, path)
-
- m.logger.debug("Node selected: " + FW_AsString(m.currentNode))
- return {
- path: m.currentPath,
- node: getNodeData(m.currentNode, m.currentPath, root)
- }
-End Sub
-
-' UIThread_updateNode - RALE "updateNode" command handler. Updates selected node
-' @param {object} args - command arguments
-' @return {object} - response of command. Contains node path and data (id, type, fields, layout etc.)
-Sub UIThread_updateNode(args) as Object
- return {
- path: m.currentPath,
- node: getNodeData(m.currentNode, m.currentPath, Invalid)
- }
-End Sub
-
-' UIThread_getNodeData - RALE "getNodeData" command handler. Returns selected node data
-' @param {object} args - command arguments
-' @return {object} - response of command. Node data (id, type, fields, layout etc.)
-Sub UIThread_getNodeData(args) as Object
- path = args["path"]
-
- if path = Invalid then
- path = m.currentPath
- node = m.currentNode
- else
- root = m.top.getScene()
- node = RALE_getNodeByPath(root, path)
- if node = Invalid then return getError("Invalid Path")
- end if
-
- return getNodeData(node, path, Invalid)
-End Sub
-
-'=======================
-' Tree View commands
-'=======================
-
-' UIThread_getItemList - RALE "getItemList" command handler. Returns node children and fields, by node path
-' @param {object} args - command arguments
-' @return {object} - response of command. List of node children and fields
-Sub UIThread_getItemList(args) as Object
- path = args["path"]
-
- root = m.top.getScene()
- node = RALE_getNodeByPath(root, path)
- if node = Invalid then return getError("Invalid Path")
-
- return getItemList(node, path)
-End Sub
-
-' UIThread_getNodeTree - RALE "getNodeTree" command handler. Returns children hierarchy by node path
-' @param {object} args - command arguments
-' @return {object} - response of command. Node children hierarchy
-Sub UIThread_getNodeTree(args) as Object
- path = args["path"]
- maxLevel = args["maxLevel"]
-
- root = m.top.getScene()
- node = RALE_getNodeByPath(root, path)
- index = RALE_getNodeIndexByPath(path)
- if node = Invalid then return getError("Invalid Path")
-
- return getNodeTree(node, index, maxLevel)
-End Sub
-
-' UIThread_getNodeById - RALE "getNodeById" command handler. Returns node with requested id
-' @param {object} args - command arguments
-' @return {object} - response of command. Found node data
-Sub UIThread_getNodeById(args) as Object
- path = args["path"]
- id = args["id"]
-
- if id = Invalid then return getError("id is required")
-
- root = m.top.getScene()
- rootNode = RALE_getNodeByPath(root, path)
- if rootNode = Invalid then return getError("Invalid Path")
-
- foundNode = getNodeById(rootNode, id)
- foundPath = RALE_getNodePath(foundNode, root)
-
- return getNodeData(foundNode, foundPath, root)
-End Sub
-
-' UIThread_getNodeByName - RALE "getNodeByName" command handler. Returns node with requested name
-' @param {object} args - command arguments
-' @return {object} - response of command. Found node path
-Sub UIThread_getNodeByName(args) as Object
- path = args["path"]
- name = args["name"]
-
- if name = Invalid then return getError("name is required")
-
- root = m.top.getScene()
- rootNode = RALE_getNodeByPath(root, path)
- if rootNode = Invalid then return getError("Invalid Path")
-
- foundNode = getNodeByName(rootNode, name)
- foundPath = RALE_getNodePath(foundNode, root)
-
- return getNodeData(foundNode, foundPath, root)
-End Sub
-
-'=======================
-' Children commands
-'=======================
-
-' UIThread_addChild - RALE "addChild" command handler. Adds new child to node by path (if no path adds to selected node)
-' @param {object} args - command arguments
-' @return {object} - response of command. Contains node children hierarchy and index
-Sub UIThread_addChild(args) as Object
- childType = args["type"]
- path = args["path"]
-
- if not FW_IsString(childType) then return getError("childType is required")
-
- index = FW_AsInteger(args["index"])
- if index = 0 AND FW_AsString(args["index"]) <> "0" then index = Invalid
-
- if path <> Invalid then
- root = m.top.getScene()
- node = RALE_getNodeByPath(root, path)
- if node = Invalid then return getError("Invalid Path")
- else
- node = m.currentNode
- path = m.currentPath
- end if
-
- result = addChild(node, childType, index)
- if result.success = true then
- index = RALE_getNodeIndexByPath(path)
- setNodeField(result.child, "rale_new_child", true, "boolean")
- return {
- tree: getNodeTree(result.child, index, 50),
- childindex: result.index
- }
- else
- return result
- end if
-End Sub
-
-' UIThread_removeChild - RALE "removeChild" command handler. Removes child from node by path (if no path removes from selected node)
-' @param {object} args - command arguments
-' @return {object} - response of command
-Sub UIThread_removeChild(args) as Object
- index = FW_AsInteger(args["index"])
- path = args["path"]
-
- if index = 0 AND FW_AsString(args["index"]) <> "0" then return getError("index is required")
-
- if path <> Invalid then
- root = m.top.getScene()
- node = RALE_getNodeByPath(root, path)
- if node = Invalid then return getError("Invalid Path")
- else
- node = m.currentNode
- path = m.currentPath
- end if
-
- return removeChild(node, index)
-End Sub
-
-' UIThread_moveChild - RALE "moveChild" command handler. Moves selected node child
-' @param {object} args - command arguments
-' @return {object} - response of command
-Sub UIThread_moveChild(args) as Object
- fromIndex = FW_AsString(args["fromIndex"])
- fromIndexInt = FW_AsInteger(fromIndex)
- if fromIndexInt = 0 AND fromIndex <> "0" then return getError("fromIndex is required")
-
- toIndex = FW_AsString(args["toIndex"])
- toIndexInt = FW_AsInteger(toIndex)
- if toIndexInt = 0 AND toIndex <> "0" then return getError("toIndex is required")
-
- return moveChild(m.currentNode, fromIndexInt, toIndexInt)
-End Sub
-
-'=======================
-' Fields commands
-'=======================
-
-' UIThread_setField - RALE "setField" command handler. Sets new value into node field (if the field doesn't exist creates it)
-' @param {object} args - command arguments
-' @return {array} - response of command. Node field list
-Sub UIThread_setField(args) as Object
- field = FW_AsString(args["field"])
- fieldType = args["type"]
- fieldValue = args["value"]
-
- if field = "" then return getError("Field ID is required")
- if RALE_convertToType(fieldValue, FW_AsString(fieldType)) = Invalid then return getError("Invalid Field Type or Value")
-
- path = m.currentPath
- nodeType = type(m.currentNode)
-
- if nodeType = "roSGNode" then
- setNodeField(m.currentNode, field, fieldValue, fieldType)
- else
- m.currentNode = setObjField(path, field, fieldValue, fieldType)
- end if
-
- m.logger.debug("Field '" + field + "' of selected node was set to " + FW_AsString(fieldValue))
- return getFieldList(m.currentNode)
-End Sub
-
-' UIThread_removeField - RALE "removeField" command handler. Remove field from node by id
-' @param {object} args - command arguments
-' @return {array} - response of command. Node field list
-Sub UIThread_removeField(args) as Object
- field = args["field"]
- if field = Invalid then return getError("Field ID is required")
-
- node = m.currentNode
- nodeType = type(node)
-
- if nodeType = "roSGNode" then
- ? ">>>>>>>>>>>>>>>>>>>>>>>"
- ? formatJson(node[field])
- ? ">>>>>>>>>>>>>>>>>>>>>>>"
- else if nodeType = "roAssociativeArray" or nodeType = "roArray" then
- if nodeType = "roArray" then field = FW_AsInteger(field)
- ? ">>>>>>>>>>>>>>>>>>>>>>>"
- ? formatJson(node[field])
- ? ">>>>>>>>>>>>>>>>>>>>>>>"
- end if
- return getFieldList(node)
-End Sub
-
-'=======================
-' Focus commands
-'=======================
-
-' UIThread_setFocus - RALE "setFocus" command handler. Sets focus in node by path
-' @param {object} args - command arguments
-' @return {object} - response of command. Status
-Sub UIThread_setFocus(args) as Object
- path = args["path"]
-
- node = m.top.getScene()
- node = RALE_getNodeByPath(node, path)
- if node = Invalid then return getError("Invalid Path")
-
- m.logger.debug(FW_AsString(node) + " was focused")
- node.setFocus(true)
- return { success: true }
-End Sub
-
-' UIThread_selectFocusedNode - RALE "selectFocusedNode" command handler. Select focused node
-' @param {object} args - command arguments
-' @return {object} - response of command. Contains node path and data (id, type, fields, layout etc.)
-Sub UIThread_selectFocusedNode(args) as Object
- root = m.top.getScene()
- node = getFocusedNodeObj(root)
- if m.currentNode.IsSameNode(node) then
- return {
- path: m.currentPath,
- node: getNodeData(node, m.currentPath, root)
- }
- else
- path = RALE_getNodePath(node, root)
- m.currentNode = node
- m.currentPath = path
- setSelectorView(node, type(node), path)
- m.logger.debug("Node selected: " + FW_AsString(node))
- return {
- path: path,
- node: getNodeData(node, path, root)
- }
- end if
-End Sub
-
-'=======================
-' Bounding Rect commands
-'=======================
-
-' UIThread_setBoundingRect - RALE "setBoundingRect" command handler. Sets properties into selected node layout
-' @param {object} args - command arguments
-' @return {object} - response of command. Node sceneBoundingRect
-Sub UIThread_setBoundingRect(args) as Object
- boundingRect = args["boundingrect"]
- if boundingRect = Invalid then return getError("boundingrect is required")
-
- node = m.currentNode
- if type(node) <> "roSGNode" then return getError("Invalid Node Type")
- currentBoundingRect = node.sceneBoundingRect()
-
- if currentBoundingRect <> Invalid then
- deltaX = 0
- deltaY = 0
- deltaWidth = 0
- deltaHeight = 0
-
- if boundingRect.x <> Invalid and boundingRect.y <> Invalid then
- deltaX = currentBoundingRect.x - boundingRect.x
- deltaY = currentBoundingRect.y - boundingRect.y
- end if
-
- if boundingRect.width <> Invalid and boundingRect.height <> Invalid then
- deltaWidth = currentBoundingRect.width - boundingRect.width
- deltaHeight = currentBoundingRect.height - boundingRect.height
- end if
-
- fields = {}
-
- if node.hasField("translation") AND (deltaY <> 0 or deltaX <> 0) then
- fields.translation = [node.translation[0] - deltaX, node.translation[1] - deltaY]
- m.logger.debug("Selected node translation was set to " + FW_AsString(fields.translation))
- end if
-
- if node.hasField("width") AND deltaWidth <> 0 then
- if node.width = 0 AND deltaWidth > 0 then
- fields.width = boundingRect.width
- else
- fields.width = node.width - deltaWidth
- end if
- m.logger.debug("Selected node width was set to " + FW_AsString(fields.width))
- end if
-
- if node.hasField("height") AND deltaHeight <> 0 then
- if node.height = 0 AND deltaHeight > 0 then
- fields.height = boundingRect.height
- else
- fields.height = node.height - deltaHeight
- end if
- m.logger.debug("Selected node height was set to " + FW_AsString(fields.height))
- end if
-
- node.setFields(fields)
- end if
- return node.sceneBoundingRect()
-End Sub
-
-'=======================
-' Layout ruler commands
-'=======================
-' UIThread_setRulerLine - TBD
-Sub UIThread_setRulerLine(args) as Object
- m.redLines.setLine(FW_AsString(args.id), args.position, args.coords)
- return { success: true }
-End Sub
-
-' UIThread_setRulerLines - TBD
-Sub UIThread_setRulerLines(args) as Object
- if args.rulerLines.Count() >= 0 then
- m.redLines.setRulerLines(args.rulerLines)
- end if
- return { success: true }
-End Sub
-
-' UIThread_removeRulerLine - TBD
-Sub UIThread_removeRulerLine(args) as Object
- m.redLines.removeLine(FW_AsString(args.id))
- return { success: true }
-End Sub
-
-' UIThread_removeRulerLine - TBD
-Sub UIThread_removeAllRulerLines(args) as Object
- m.redLines.removeAllLines()
- return { success: true }
-End Sub
-
-'=======================
-' Registry commands
-'=======================
-
-' UIThread_getRegistrySections - TBD
-Sub UIThread_getRegistrySections(args) as Object
- return getRegistrySections()
-End Sub
-
-' UIThread_addRegistrySection - TBD
-Sub UIThread_clearRegistry(args) as Object
- return clearRegistry()
-End Sub
-
-' UIThread_addRegistrySection - TBD
-Sub UIThread_addRegistrySection(args) as Object
- name = args.name
- section = args.section
-
- if not FW_IsString(name) or name = "" then return getError("Invalid name")
- if not FW_IsAssociativeArray(section) then return getError("Invalid section. Expected an object")
-
- return addRegistrySection(name, section)
-End Sub
-
-' UIThread_removeRegistrySection - TBD
-Sub UIThread_removeRegistrySection(args) as Object
- name = args.name
-
- if not FW_IsString(name) or name = "" then return getError("Invalid name")
-
- return removeRegistrySection(name)
-End Sub
-
-' UIThread_addRegistryField - TBD
-Sub UIThread_addRegistryField(args) as Object
- sectionName = args.sectionName
- key = args.key
- value = args.value
-
- if not FW_IsString(sectionName) or sectionName = "" then return getError("Invalid section name")
- if not FW_IsString(key) or key = "" then return getError("Invalid key")
- if not FW_IsString(value) then return getError("Invalid value")
-
- return addRegistryField(sectionName, key, value)
-End Sub
-
-' UIThread_removeRegistryField - TBD
-Sub UIThread_removeRegistryField(args) as Object
- sectionName = args.sectionName
- key = args.key
-
- if not FW_IsString(sectionName) or sectionName = "" then return getError("Invalid section name")
- if not FW_IsString(key) or key = "" then return getError("Invalid key")
-
- return removeRegistryField(sectionName, key)
-End Sub
-
-' UIThread_editRegistryField - TBD
-Sub UIThread_editRegistryField(args) as Object
- sectionName = args.sectionName
- key = args.key
- newKey = args.newKey
- newValue = args.newValue
-
- if not FW_IsString(sectionName) or sectionName = "" then return getError("Invalid section name")
- if not FW_IsString(key) or key = "" then return getError("Invalid key")
- if not FW_IsString(newKey) or newKey = "" then return getError("Invalid newKey")
-
- return editRegistryField(sectionName, key, newKey, newValue)
-End Sub
-
-' UIThread_log - TBD
-Sub UIThread_log(args) as Object
- m.logger.logMessage(args.message, m.logger.verbosityMap[args.status])
-End Sub
-
-' UIThread_setLogVerbosity - TBD
-Sub UIThread_setLogVerbosity(args) as Object
- level = args.level
-
- if not FW_IsInteger(level) then return getError("Invalid level")
-
- m.logger.setVerbosity(args.level)
- return { success: true }
-End Sub
-
-' UIThread_setLogFormat - TBD
-Sub UIThread_setLogFormat(args) as Object
- format = args.format
-
- if not FW_IsString(format) then return getError("Invalid format")
-
- m.logger.setFormat(args.format)
- return { success: true }
-End Sub
-
-'=======================
-' Helpers functions
-'=======================
-
-' getLayout - Returns node layout fields (boundingRect, resolution, isMovable, isHeightResizable, isWidthResizable)
-' @param {object} node - node
-' @param {object} root - root of nodes (main scene)
-' @return {object} - node layout
-Sub getLayout(node, root) as Object
- if not FW_IsSGNode(node) then return getError("Invalid Node Type")
-
- if root = Invalid then root = m.top.getScene()
-
- parent = node.getParent()
-
- isWidthResizable = node.hasField("width")
- isHeightResizable = node.hasField("height")
- isMovable = false
-
- if parent <> Invalid and not m.sceneBG.isSameNode(node) then
- isMovable = node.hasField("translation") and parent.ParentSubtype("LayoutGroup") <> ""
- end if
-
- return {
- isMovable : isMovable,
- isHeightResizable : isHeightResizable,
- isWidthResizable : isWidthResizable,
- boundingRect : node.sceneBoundingRect(),
- resolution : root.getField("currentDesignResolution")
- }
-End Sub
-
-' getItemObj - Returns node object
-' @param {object} item - node or filed
-' @param {string} index - field id or child index
-' @return {object} - node data object
-Sub getItemObj(item, index) as Dynamic
- itemType = type(item)
-
- if itemType = "roSGNode" then
- return {
- index: index,
- id: item.id,
- childrenCount: item.getChildCount(),
- subtype: item.subtype(),
- type: itemType,
- value: "{object}"
- isExposed: FW_AsBoolean(item.isExternallyExposed)
- }
- else if itemType = "roArray" or itemType = "roAssociativeArray" then
- return {
- id: index,
- type: itemType,
- value: "{object}"
- }
- else
- return {
- id: index,
- type: itemType,
- value: FW_AsString(item)
- }
- end if
-End Sub
-
-' getFieldList - Returns node field list
-' @param {object} node - node
-' @return {array} - list of fields
-Sub getFieldList(node) as Object
- nodeType = type(node)
-
- if nodeType = "roSGNode" then
- fields = node.getFields()
- else if nodeType = "roArray" or nodeType = "roAssociativeArray" then
- fields = node
- else
- return getError("Invalid Node Type")
- end if
-
- fieldList = {}
-
- result = 0
- if type(fields) = "roArray" then
- count = fields.count() - 1
- for i = 0 to count
- id = i.ToStr()
- fieldList[id] = { item: getItemObj(fields[i], i) }
- fieldList[id].item.id = i
- end for
- else
- keys = fields.keys()
- for each fieldId in keys
- fieldList[fieldId] = { item: getItemObj(fields[fieldId], fieldId) }
- if nodeType = "roSGNode" then fieldList[fieldId].item.fieldType = node.getFieldType(fieldId)
- end for
- end if
-
- return fieldList
-End Sub
-
-' getChildList - Returns node children list
-' @param {object} node - node
-' @return {array} - list of children
-Sub getChildList(node) as Object
- nodeType = type(node)
-
- if nodeType = "roSGNode" then
- childList = []
- children = node.getChildren(-1, 0)
- count = children.count()
- if count > 0 then
- count--
- for i = 0 to count
- if children[i] <> Invalid then
- childList[i] = { item: getItemObj(children[i], i) }
- end if
- end for
- end if
- return childList
- else
- return getError("Invalid Node Type")
- end if
-End Sub
-
-' getItemList - Returns node children list and node data
-' @param {object} node - node
-' @param {object} index - node index
-' @return {object} - node data object and list of node children
-Sub getItemList(node, index) as Object
- item = { item: getItemObj(node, index) }
- nodeType = type(node)
- if nodeType = "roSGNode" then
- item.childList = getChildList(node)
- else
- return getError("Invalid Node Type")
- end if
- return item
-End Sub
-
-' getNodeTree - Goes through node children and returns node children hierarchy
-' @param {object} node - node or filed
-' @param {string} id - node index or filed id
-' @return {array} - node children hierarchy
-Sub getNodeTree(node, id, maxLevel) as Object
- item = {
- item: getItemObj(node, id),
- childList: []
- }
-
- result = RALE_forEachChild(node, { maxLevel: maxLevel }, getNodeTreeCallback, { item: item })
-
- if not result then
- return getError("Invalid Node Type")
- end if
-
- return item
-End Sub
-
-Sub getNodeTreeCallback(node, index, parentObj, childObj, storage) as Boolean
-
- if parentObj.item = Invalid then
- parentObj.item = storage.item
- end if
-
- childItem = {
- item : getItemObj(node, index),
- childList : []
- }
-
- parentObj.item.childlist[index] = childItem
-
- if childObj <> Invalid then
- childObj.item = childItem
- end if
-
- return true
-End Sub
-
-' getNodeById - Search for node by id
-' @param {object} node - root node
-' @param {string} id - node id
-' @return {object} - found node
-Sub getNodeById(rootNode, id) as Object
-
- if rootNode.id = id then
- return rootNode
- end if
-
- storage = {
- node: Invalid,
- id: id
- }
-
- result = RALE_forEachChild(rootNode, {}, getNodeByIdCallback, storage)
-
- if not result then
- return getError("Invalid Node Type")
- end if
-
- return storage.node
-End Sub
-
-Sub getNodeByIdCallback(node, index, parentObj, childObj, storage) as Boolean
-
- if node.id = storage.id then
- storage.node = node
- return false
- end if
-
- return true
-End Sub
-
-' getNodeByName - Search for node by name (subtype)
-' @param {object} node - root node
-' @param {string} name - node name (subtype)
-' @return {object} - found node
-Sub getNodeByName(rootNode, name) as Object
-
- if rootNode.subtype() = name then
- return rootNode
- end if
-
- storage = {
- node: Invalid,
- name: name
- }
-
- result = RALE_forEachChild(rootNode, {}, getNodeByNameCallback, storage)
-
- if not result then
- return getError("Invalid Node Type")
- end if
-
- return storage.node
-End Sub
-
-Sub getNodeByNameCallback(node, index, parentObj, childObj, storage) as Boolean
-
- if node.subtype() = storage.name then
- storage.node = node
- return false
- end if
-
- return true
-End Sub
-
-' getNodeData - Returns node children hierarchy
-' @param {object} node - node or filed
-' @param {array} path - path to node
-' @param {object} root - root of nodes (main scene)
-' @return {object} - node data (item, fieldlist, layout)
-Sub getNodeData(node, path, root) as Object
- index = RALE_getNodeIndexByPath(path)
- if index = Invalid then return getError("Invalid Path")
-
- result = {
- item: getItemObj(node, index),
- fieldlist: getFieldList(node),
- layout: getLayout(node, root)
- }
- if type(node) = "roSGNode" then result.childlist = getChildList(node)
-
- return result
-End Sub
-
-' addChild - Adds child to node by type and index
-' @param {object} node - parent node
-' @param {string} childType - path to node
-' @param {string} index - child index
-' @return {object} - status
-Sub addChild(node, childType, index) as Object
- if not FW_IsSGNode(node) then return getError("Cannot Add Child. Invalid Node Type")
-
- child = CreateObject("roSGNode", childType)
- if not FW_IsSGNode(child) then return getError("Cannot Add Child. Invalid Component Type")
-
- childCount = node.getChildCount()
- if FW_IsInteger(index) and index < childCount then
- node.insertChild(child, index)
- else
- index = childCount
- node.appendChild(child)
- end if
-
- addedChild = node.getChild(index)
- if type(addedChild) = "roSGNode" and addedChild.isSameNode(child) then
- m.logger.debug("Child " + childType + " was added to " + FW_AsString(node) + " by index " + FW_AsString(index))
- return { success: true, child: addedChild, index: index }
- else
- return getError("Cannot Add Child")
- end if
-End Sub
-
-' removeChild - Removes child from node by index
-' @param {object} node - parent node
-' @param {string} index - child index
-' @return {object} - status
-Sub removeChild(node, index as Integer) as Object
- if not FW_IsSGNode(node) then return getError("Invalid Node Type")
- count = node.getChildCount()
- if FW_IsSGNode(node.getChild(index)) then
- node.removeChildIndex(index)
- if node.getChildCount() < count then
- m.logger.debug("Child with index " + FW_AsString(index) + " was removed from " + FW_AsString(node))
- return { success: true }
- end if
- return getError("Node cannot be removed")
- else
- return getError("No child with this index")
- end if
-End Sub
-
-' moveChild - Moves node child by index to another position
-' @param {object} node - parent node
-' @param {string} fromIndex - current child index
-' @param {string} toIndex - index where you want to move
-' @return {object} - status
-Sub moveChild(node, fromIndex, toIndex) as Object
- if not FW_IsSGNode(node) then return getError("Invalid Node Type")
-
- if fromIndex >= 0 AND toIndex >= 0
- child = node.getChild(fromIndex)
- if child <> Invalid then
- node.removeChildIndex(fromIndex)
- if toIndex > fromIndex then toIndex--
- node.insertChild(child, toIndex)
-
- m.logger.debug("Child of " + FW_AsString(node) + " was moved from index " + FW_AsString(fromIndex) + " to index " + FW_AsString(toIndex))
- return { success: true }
- else
- return getError("No child with this index")
- end if
- else
- return getError("fromIndex and toIndex must be positive integer")
- end if
-End Sub
-
-' setSelectorView - Shows selector (live) view for node
-' @param {object} node - node
-' @param {string} nodeType - type of node
-' @param {array} nodePath - path to node
-' @return {object} - status
-Function setSelectorView(node, nodeType, nodePath) as Object
- if m.selectorView <> Invalid then
- if m.showSelectorView and nodeType = "roSGNode" and nodePath.count() > 0 then
- m.selectorView.attachedView = node
- else
- m.selectorView.attachedView = Invalid
- end if
- end if
-End Function
-
-' setNodeField - Sets field into node
-' @param {object} node - node
-' @param {string} field - field id
-' @param {dynamic} value - field value
-' @param {string} fieldType - field type
-Sub setNodeField(node, field, value, fieldType) as Object
- fields = {}
- if fieldType = Invalid then
- fields[field] = value
- if node.hasField(field) then
- node.setFields(fields)
- else
- node.addFields(fields)
- end if
- else
- fields[field] = RALE_convertToType(value, fieldType)
-' if node.hasField(field) and node.getFieldType(field) <> 'fieldType then
-' node.removeField(field)
-' end if
-'
-' if not node.hasField(field) then
-' node.addField(field, RALE_parseType(fieldType), false)
-' end if
- node.setFields(fields)
- end if
-End Sub
-
-' setObjField - Sets field into AssociativeArray
-' @param {array} parentPath - node
-' @param {string} field - field id
-' @param {dynamic} value - field value
-' @param {string} fieldType - field type
-' @return {object} - status
-Sub setObjField(parentPath, field, value, fieldType) as Object
- if fieldType <> Invalid then
- value = RALE_convertToType(value, fieldType)
- end if
- return setInParentNode(parentPath, field, value)
-End Sub
-
-' setInParentNode - Sets field into parent node
-' @param {array} path - path to field
-' @param {string} field - field id
-' @param {dynamic} value - field value
-' @return {object} - parent node
-Function setInParentNode(path, field, value)
- root = m.top.getScene()
- parentPath = []
- parentPath.append(path)
- nodeList = RALE_getNodeListByPath(root, path)
- if nodeList = Invalid then return getError("Invalid Path")
-
- index = nodeList.count() - 1
- parent = nodeList[index]
- if type(parent) = "roSGNode" then
- setNodeField(parent, field, value, Invalid)
- return parent
- end if
-
- while type(parent) <> "roSGNode"
- if type(parent) = "roArray" then
- field = FW_AsInteger(field)
- if field > parent.count() then
- field = parent.count()
- end if
- parent[field] = value
- else
- parent[field] = value
- end if
- value = parent
- index--
- field = path[index].field
- parent = nodeList[index]
- parentPath.pop()
- end while
-
- parent = RALE_getNodeByPath(root, parentPath)
- setNodeField(parent, field, value, Invalid)
- return RALE_getNodeByPath(root, path)
-End Function
-
-' setFocus - Focus node
-' @param {object} node - node
-Sub setFocus(node) as Object
- if not FW_IsSGNode(node) then return getError("Invalid Node Type")
- node.setFocus(true)
-End Sub
-
-' getFocusedNodeObj - Returns focused node
-' @param {object} root - root
-' @param {object} maxDeep - search depth
-' @return {object} - focused node
-Function getFocusedNodeObj(root, maxDeep = 25) as Object
- node = root
- focusedChild = node.focusedChild
- while maxDeep > 0 AND focusedChild <> Invalid AND not node.isSameNode(focusedChild)
- node = focusedChild
- focusedChild = node.focusedChild
- maxDeep--
- end while
- return node
-End Function
-
-' getRegistrySections - Returns map of roRegistry
-' @return {object} - sections
-Function getRegistrySections() as Object
- sections = {}
-
- RALE_forEachRegistryField(getRegistrySectionsCallback, sections)
-
- return sections
-End Function
-
-Sub getRegistrySectionsCallback(value, key, section, sections) as Boolean
- if not FW_IsAssociativeArray(sections[section]) then
- sections[section] = {}
- end If
-
- sections[section][key] = value
-
- return true
-End Sub
-
-' clearRegistry - Clear roRegistry
-Function clearRegistry() as Object
- RALE_forEachRegistrySection(clearRegistryCallback, {})
-
- return { success: true }
-End Function
-
-Sub clearRegistryCallback(section, sectionName, storage) as Object
- return removeRegistrySection(sectionName)
-End Sub
-
-' addRegistrySection - TBD
-' @return {object} - sections
-Function addRegistrySection(sectionName, section) as Object
- RegistrySection = CreateObject("roRegistrySection", sectionName)
- keys = section.keys()
-
- for each key in keys
- RegistrySection.write(key, section[key])
- end for
-
- RegistrySection.flush()
- m.logger.debug("Registry section " + sectionName + " was added to roRegistry")
-
- return { success: true }
-End Function
-
-' removeRegistrySection - TBD
-' @return {object} - sections
-Function removeRegistrySection(sectionName) as Object
- Registry = CreateObject("roRegistry")
-
- success = Registry.delete(sectionName)
-
- Registry.flush()
-
- m.logger.debug("Registry section " + sectionName + " was removed from roRegistry")
-
- return { success: success }
-End Function
-
-' addRegistryField - TBD
-' @return {object} - sections
-Function addRegistryField(sectionName, key, value) as Object
- RegistrySection = CreateObject("roRegistrySection", sectionName)
-
- success = RegistrySection.write(key, value)
-
- m.logger.debug("Field " + key + " with value " + value + " was added to " + sectionName + " registry section")
-
- return { success: success }
-End Function
-
-' removeRegistryField - TBD
-' @return {object} - sections
-Function removeRegistryField(sectionName, key) as Object
- RegistrySection = CreateObject("roRegistrySection", sectionName)
-
- success = RegistrySection.delete(key)
-
- m.logger.debug("Field " + key + " was removed from " + sectionName + " registry section")
-
- return { success: success }
-End Function
-
-' getRegistrySections - TBD
-' @return {object} - sections
-Function editRegistryField(sectionName, key, newKey, newValue) as Object
- result = removeRegistryField(sectionName, key)
-
- if result.success then
- result = addRegistryField(sectionName, newKey, newValue)
- end if
-
- return result
-End Function
-
-' getError - Returns error object
-' @param {string} message - error message
-Function getError(message as String) as Object
- m.logger.error(message)
- return { error: { message: message } }
-End Function
-
-
-' @desc TrackerTask init function
-Sub init()
- m.top.functionName = "tracker"
- m.top.control = "RUN"
-
- m.config = RALE_Config()
- m.logger = RALE_Logger(m.config.defaultLogLevel, m.config.logFormat)
- m.sceneBG = m.top.GetScene().getChild(0)
- m.raleVersion = "2.1.7"
- m.sessionId = CreateObject("roDeviceInfo").GetRandomUUID()
-
- m.logger.info("Roku Advanced Layout Editor v." + m.raleVersion)
-End Sub
-
-' tracker - TrackerTask run function
-Sub tracker()
- appInfo = CreateObject("roAppInfo")
- handlersMap = getCommandMap()
-
- RALE_InfoLog("TrackerTask run")
-
- buffer = CreateObject("roByteArray")
- buffer[m.config.bufferSize] = 0
- messagePort = CreateObject("roMessagePort")
- addr = CreateObject("roSocketAddress")
-
- inputPort = CreateObject("roMessagePort")
- inputObj = CreateObject("roInput")
- inputObj.SetMessagePort(inputPort)
-
- while True
- raleEnabled = true
- port = 0
- RALE_InfoLog("Waiting on ECP input request")
- msg = wait(0, inputPort)
-
- if type(msg) = "roInputEvent"
- if msg.IsInput()
- info = msg.GetInfo()
- if type(info) = "roAssociativeArray" and info.rale <> Invalid then
- port = FW_AsInteger(info.port)
- end if
-
- nonDev = FW_AsBoolean(info.nonDev)
-
- end if
- end if
-
- if raleEnabled and port > m.config.minSocketPort and port < m.config.maxSocketPort then
- socketConnection(addr, messagePort, port, buffer, handlersMap, m.config)
- end if
- end while
-
-End Sub
-
-' socketConnection - Starts socket connection. Keep alive while connection won't be closed
-' @param {object} addr - roSocketAddress
-' @param {object} messagePort - roMessagePort
-' @param {number} port - socket connection port
-' @param {array} buffer - buffer for socket packets
-' @param {object} handlersMap - map that contains all RALE commands handlers
-' @param {object} config - configuration constants
-' @return {string} - connection status
-Sub socketConnection(addr, messagePort, port, buffer, handlersMap, config) as String
- connections = {}
- appManager = createObject("roAppManager")
- screensaverTimer = CreateObject("roTimespan")
- screensaverTimer.Mark()
-
- addr.setPort(port)
-
- tcpListen = CreateObject("roStreamSocket")
- tcpListen.setMessagePort(messagePort)
- tcpListen.setAddress(addr)
- tcpListen.notifyReadable(true)
- tcpListen.listen(4)
-
- wasConnected = false
-
- RALE_InfoLog("Start socket server on port " + FW_AsString(port))
-
- while True
-
- if not wasConnected then
- event = wait(3000, messagePort)
- if event = Invalid then
- tcpListen.close()
- RALE_WarningLog("No 'init' command received. Socket connection closed")
- return "connection timeout"
- end if
- else
- event = wait(config.commandTimeout, messagePort)
- end if
-
- ' Resets the screensaver timer
- if screensaverTimer.TotalMilliseconds() > config.screensaverResetTimeout then
- screensaverTimer.Mark()
- appManager.UpdateLastKeyPressTime()
- end if
-
- ' ? type(event)
- if type(event) = "roSocketEvent"
- wasConnected = true
- changedID = event.getSocketID()
- if changedID = tcpListen.getID() and tcpListen.isReadable()
- ' New
- newConnection = tcpListen.accept()
- if newConnection = Invalid
- RALE_WarningLog("Connection accept failed")
- else
- RALE_InfoLog("Accepted new connection " + FW_AsString(newConnection.getID()))
-
- newConnection.notifyReadable(true)
- newConnection.setMessagePort(messagePort)
- connections[Stri(newConnection.getID())] = newConnection
- end if
- else
- ' Activity on an open connection
- connection = connections[Stri(changedID)]
- closed = False
- if connection.isReadable()
- received = connection.receive(buffer, 0, 100024)
- if received > 0
- timer = CreateObject("roTimespan")
- timer.Mark()
-
- valueType = type(m.lastUdpPacketRemainingContents)
- if NOT ((valueType = "String") OR (valueType = "roString")) then
- m.lastUdpPacketRemainingContents = ""
- end if
- remainingString = m.lastUdpPacketRemainingContents + buffer.ToAsciiString()
- m.lastUdpPacketRemainingContents = ""
- 'print "incoming string " remainingString
- startIndex = 0
- continueToLoop = true
- while continueToLoop
- index = remainingString.instr(startIndex, "}{")
- if index < 0 then
- str = remainingString
- continueToLoop = false
- else
- index++
- str = remainingString.left(index)
- remainingString = remainingString.mid(index)
- if remainingString.right(1) <> "}" and remainingString.instr("}{") < 0 then
- m.lastUdpPacketRemainingContents = remainingString
- exit while
- end if
- end if
- end while
-
- request = ParseJson(str)
- buffer = CreateObject("roByteArray")
- buffer[100024] = 0
-
- if request <> Invalid then
- response = {}
- if request["command"] <> Invalid then
-
- handler = handlersMap[request["command"]]
- if handler <> Invalid then
- RALE_DebugLog("Handling command: " + request["command"])
- RALE_DebugLog("Received arguments: " + FW_AsString(request["args"]))
-
- response = callCommand(handler, request["args"])
- else
- RALE_ErrorLog("No such command: " + request["command"])
-
- response = getError("No such command")
- end if
- end if
- id = request.uuid
- idLen = FW_AsString(Len(id))
- json = FormatJson(response)
- res = "[start][uuid:" + idLen + "]" + id + json + "[end]"
-
- resList = RALE_splitStringByLength(res, 3000)
- count = resList.count() - 1
- for i = 0 to count
- connection.SendStr(resList[i])
- sleep(20)
- end for
- RALE_DebugLog("Command handled in: " + FW_AsString(timer.TotalMilliseconds()) + "ms")
- end if
- else if received=0 ' client closed
- closed = True
- end if
- end if
- if closed or not connection.eOK()
- connection.close()
- connections.delete(Stri(changedID))
- exit while
- end if
- end if
- end if
- end while
-
- tcpListen.close()
- for each id in connections
- connections[id].close()
- end for
-
- RALE_InfoLog("Socket connection closed")
-
- return "connection closed"
-End Sub
-
-'IMPORTS=
-'=====================
-' Types
-'=====================
-
-'*************************************************
-' FW_IsXmlElement - check if value contains XMLElement interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains XMLElement interface, else return false
-'*************************************************
-Function FW_IsXmlElement(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifXMLElement") <> invalid
-End Function
-
-'*************************************************
-' FW_IsFunction - check if value contains Function interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains Function interface, else return false
-'*************************************************
-Function FW_IsFunction(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifFunction") <> invalid
-End Function
-
-'*************************************************
-' FW_IsBoolean - check if value contains Boolean interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains Boolean interface, else return false
-'*************************************************
-Function FW_IsBoolean(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifBoolean") <> invalid
-End Function
-
-'*************************************************
-' FW_IsInteger - check if value type equals Integer
-' @param value As Dynamic
-' @return As Boolean - true if value type equals Integer, else return false
-'*************************************************
-Function FW_IsInteger(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifInt") <> invalid And (Type(value) = "roInt" Or Type(value) = "roInteger" Or Type(value) = "Integer")
-End Function
-
-'*************************************************
-' FW_IsFloat - check if value contains Float interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains Float interface, else return false
-'*************************************************
-Function FW_IsFloat(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifFloat") <> invalid
-End Function
-
-'*************************************************
-' FW_IsDouble - check if value contains Double interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains Double interface, else return false
-'*************************************************
-Function FW_IsDouble(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifDouble") <> invalid
-End Function
-
-'*************************************************
-' FW_IsLongInteger - check if value contains LongInteger interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains LongInteger interface, else return false
-'*************************************************
-Function FW_IsLongInteger(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifLongInt") <> invalid
-End Function
-
-
-'*************************************************
-' FW_IsNumber - check if value contains LongInteger or Integer or Double or Float interface
-' @param value As Dynamic
-' @return As Boolean - true if value is number, else return false
-'*************************************************
-Function FW_IsNumber(value As Dynamic) As Boolean
- Return FW_IsLongInteger(value) or FW_IsDouble(value) or FW_IsInteger(value) or FW_IsFloat(value)
-End Function
-
-'*************************************************
-' FW_IsList - check if value contains List interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains List interface, else return false
-'*************************************************
-Function FW_IsList(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifList") <> invalid
-End Function
-
-'*************************************************
-' FW_IsArray - check if value contains Array interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains Array interface, else return false
-'*************************************************
-Function FW_IsArray(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifArray") <> invalid
-End Function
-
-'*************************************************
-' FW_IsAssociativeArray - check if value contains AssociativeArray interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains AssociativeArray interface, else return false
-'*************************************************
-Function FW_IsAssociativeArray(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifAssociativeArray") <> invalid
-End Function
-
-'*************************************************
-' FW_IsSGNode - check if value contains SGNodeChildren interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains SGNodeChildren interface, else return false
-'*************************************************
-Function FW_IsSGNode(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifSGNodeChildren") <> invalid
-End Function
-
-'*************************************************
-' FW_IsString - check if value contains String interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains String interface, else return false
-'*************************************************
-Function FW_IsString(value As Dynamic) As Boolean
- Return FW_IsValid(value) And GetInterface(value, "ifString") <> invalid
-End Function
-
-'*************************************************
-' FW_IsNotEmptyString - check if value contains String interface and length more 0
-' @param value As Dynamic
-' @return As Boolean - true if value contains String interface and length more 0, else return false
-'*************************************************
-Function FW_IsNotEmptyString(value As Dynamic) As Boolean
- Return FW_IsString(value) and len(value) > 0
-End Function
-
-'*************************************************
-' FW_IsDateTime - check if value contains DateTime interface
-' @param value As Dynamic
-' @return As Boolean - true if value contains DateTime interface, else return false
-'*************************************************
-Function FW_IsDateTime(value As Dynamic) As Boolean
- Return FW_IsValid(value) And (GetInterface(value, "ifDateTime") <> invalid Or Type(value) = "roDateTime")
-End Function
-
-'*************************************************
-' FW_IsValid - check if value initialized and not equal invalid
-' @param value As Dynamic
-' @return As Boolean - true if value initialized and not equal invalid, else return false
-'*************************************************
-Function FW_IsValid(value As Dynamic) As Boolean
- Return Type(value) <> "" And value <> invalid
-End Function
-
-'*************************************************
-' FW_ValidStr - return value if his contains String interface else return empty string
-' @param value As Object
-' @return As String - value if his contains String interface else return empty string
-'*************************************************
-Function FW_ValidStr(obj As Object) As String
- if obj <> invalid and GetInterface(obj, "ifString") <> invalid
- return obj
- else
- return ""
- endif
-End Function
-
-'*************************************************
-' FW_AsString - convert input to String if this possible, else return empty string
-' @param input As Dynamic
-' @return As String - return converted string
-'*************************************************
-Function FW_AsString(input As Dynamic) As String
- If FW_IsValid(input) = False Then
- Return ""
- Else If FW_IsString(input) Then
- Return input
- Else If FW_IsInteger(input) or FW_IsLongInteger(input) or FW_IsBoolean(input)Then
- Return input.ToStr()
- Else If FW_IsFloat(input) or FW_IsDouble(input) Then
- Return Str(input).Trim()
- Else If FW_IsBoolean(input) Then
- If input Then
- Return "true"
- Else
- Return "false"
- End If
- Else If FW_IsSGNode(input) Then
- return input.subtype()
- Else If FW_IsArray(input) Then
- result = ""
- For each item in input
- result = result + FW_AsString(item) + ", "
- End For
- Return "[" + Left(result, Len(result) - 2) + "]"
- Else If FW_IsAssociativeArray(input) Then
- result = ""
- For each key in input
- result = result + key + " : " + FW_AsString(input[key]) + ", "
- End For
- Return "{ " + Left(result, Len(result) - 2) + " }"
- End If
- return ""
-End Function
-
-'*************************************************
-' FW_AsInteger - convert input to Integer if this possible, else return 0
-' @param input As Dynamic
-' @return As Integer - return converted Integer
-'*************************************************
-Function FW_AsInteger(input As Dynamic) As Integer
- If FW_IsValid(input) = False Then
- Return 0
- Else If FW_IsString(input) Then
- Return input.ToInt()
- Else If FW_IsInteger(input) Then
- Return input
- Else If FW_IsFloat(input) or FW_IsDouble(input) or FW_IsLongInteger(input) Then
- Return Int(input)
- Else
- Return 0
- End If
-End Function
-
-'*************************************************
-' FW_AsLongInteger - convert input to LongInteger if this possible, else return 0
-' @param input As Dynamic
-' @return As Integer - return converted LongInteger
-'*************************************************
-Function FW_AsLongInteger(input As Dynamic) As LongInteger
- If FW_IsValid(input) = False Then
- Return 0
- Else If FW_IsString(input) Then
- Return FW_AsInteger(input)
- Else If FW_IsLongInteger(input) or FW_IsFloat(input) or FW_IsDouble(input) or FW_IsInteger(input) Then
- Return input
- Else
- Return 0
- End If
-End Function
-
-'*************************************************
-' FW_AsFloat - convert input to Float if this possible, else return 0.0
-' @param input As Dynamic
-' @return As Float - return converted Float
-'*************************************************
-Function FW_AsFloat(input As Dynamic) As Float
- If FW_IsValid(input) = False Then
- Return 0.0
- Else If FW_IsString(input) Then
- Return input.ToFloat()
- Else If FW_IsInteger(input) Then
- Return (input / 1)
- Else If FW_IsFloat(input) or FW_IsDouble(input) or FW_IsLongInteger(input) Then
- Return input
- Else
- Return 0.0
- End If
-End Function
-
-'*************************************************
-' FW_AsDouble - convert input to Double if this possible, else return 0.0
-' @param input As Dynamic
-' @return As Float - return converted Double
-'*************************************************
-Function FW_AsDouble(input As Dynamic) As Double
- If FW_IsValid(input) = False Then
- Return 0.0
- Else If FW_IsString(input) Then
- Return FW_AsFloat(input)
- Else If FW_IsInteger(input) or FW_IsLongInteger(input) or FW_IsFloat(input) or FW_IsDouble(input) Then
- Return input
- Else
- Return 0.0
- End If
-End Function
-
-'*************************************************
-' FW_AsBoolean - convert input to Boolean if this possible, else return False
-' @param input As Dynamic
-' @return As Boolean
-'*************************************************
-Function FW_AsBoolean(input As Dynamic) As Boolean
- If FW_IsValid(input) = False Then
- Return False
- Else If FW_IsString(input) Then
- Return LCase(input) = "true"
- Else If FW_IsInteger(input) Or FW_IsFloat(input) Then
- Return input <> 0
- Else If FW_IsBoolean(input) Then
- Return input
- Else
- Return False
- End If
-End Function
-
-'*************************************************
-' FW_AsArray - if type of value equals array return value, else return array with one element [value]
-' @param value As Object
-' @return As Object - roArray
-'*************************************************
-Function FW_AsArray(value As Object) As Object
- If FW_IsValid(value)
- If Not FW_IsArray(value) Then
- Return [value]
- Else
- Return value
- End If
- End If
- Return []
-End Function
-
-'*************************************************
-' FW_ValidAA - check if obj contains all keys
-' @param obj As Object - roAssociativeArray
-' @param keys as Object - roArray of keys(string) to check
-' @param delim as String - key delimiter (default = ".")
-' @return As Boolean - return true if type of obj equals AssociativeArray and obj contains all keys, else return false
-'*************************************************
-Function FW_ValidAA(obj As Object, keys as Object, delim = "." as String) as Boolean
- 'All keys on level 0
- if not FW_IsAssociativeArray(obj) or not FW_IsNotEmptyString(delim) or not FW_isArray(keys) then
- return false
- end if
- for each key in Keys
- subKeys = key.split(delim)
- aa_check = obj
- 'go down the hierarchy key.subkey.subsubkey...
- for each subkey in subKeys
- if FW_IsAssociativeArray(aa_check) and aa_check[subkey] <> invalid then
- aa_check = aa_check[subkey]
- else
- print "Key::"; key
- print "subkey::"; subkey
- 'printAA(obj)
- return false
-
- end if
- end for
-
- end for
- return true
-end Function
-
-'*************************************************
-' FW_GetSubElement - check if obj contains subElementTree element and return him
-' @param element as Dynamic - roAssociativeArray
-' @param subElementTree as Dynamic - String keys tree
-' @param delim as String - key delimiter (default = ".")
-' @return As Dynamic - if exist obj[subElementTree] value else invalid
-'*************************************************
-function FW_GetSubElement(element as Dynamic, subElementTree as Dynamic, delim = "." as String) as Dynamic
- if FW_IsValid(element) = false or FW_IsValid(subElementTree) = false then
- return invalid
- end if
-
- subElementTreeArray = []
- result = element
-
- if FW_IsNotEmptyString(subElementTree) and FW_IsNotEmptyString(delim) then
- subElementTreeArray = subElementTree.split(delim)
- else if FW_IsArray(subElementTree) then
- subElementTreeArray = subElementTree
- else
- result = invalid
- end if
-
- for each field in subElementTreeArray
- if FW_IsSGNode(result) then
- key = FW_AsString(field)
- if result.HasField(key) then
- result = result.GetField(key)
- else
- index = FW_AsInteger(field)
- if (index = 0 and key <> "0") or index < 0 or index >= result.GetChildCount() then
- result = invalid
- exit for
- end if
- result = result.GetChild(index)
- end if
- else if FW_IsAssociativeArray(result) then
- result = result.LookupCI(FW_AsString(field)) 'use case-insensitive lookup for AAs
- else if FW_IsArray(result) then
- index = FW_AsInteger(field)
- if (index = 0 and FW_AsString(field) <> "0") or index < 0 or index >= result.Count() then 'index is not an integer or out of range?
- result = invalid
- exit for
- end if
- result = result[index]
- else
- result = invalid
- exit for
- end if
- end for
-
- return result
-end function
-
-
-' RALE_parseType - Parse type name to brs type
-' @param {string} _type - type
-' @return {string} - brs type
-Function RALE_parseType(_type as String) as String
- _type = LCase(_type)
- convertMap = {
- "rointeger" : "integer",
- "roint" : "integer",
- "int" : "integer",
- "num" : "integer",
- "number" : "integer",
-
- "rofloat" : "float",
-
- "rostring" : "string",
- "text" : "string",
- "str" : "string",
-
- "roboolean" : "bool",
- "boolean" : "bool",
-
- "rosgnode" : "node",
-
- "roarray" : "array",
- "array" : "array",
- "arr" : "array",
-
- "object" : "assocarray",
- "associativearray" : "assocarray",
- "roassociativearray" : "assocarray"
- }
- if convertMap[_type] <> Invalid then return convertMap[_type]
- return _type
-End function
-
-' RALE_convertToType - Convert variable to type
-' @param {dynamic} value - variable value
-' @param {string} _type - type to which you want to convert
-' @return {dynamic} - new variable value
-Function RALE_convertToType(value as Dynamic, _type as String) as Dynamic
- _type = RALE_parseType(_type)
-
- convertMap = {
- "integer" : FW_AsInteger,
- "float" : FW_AsFloat,
- "bool" : FW_AsBoolean,
- "string" : FW_AsString,
- "array" : FW_AsArray,
- }
-
- if _type = "assocarray" and type(value) <> "roAssociativeArray" then
- value = CreateObject("roAssociativeArray")
- end if
- if _type = "array" and type(value) <> "roArray" then
- value = FW_AsString(value).split(",")
- end if
- if _type = "node" then
- value = CreateObject("roSGNode", FW_AsString(value))
- end if
-
- if convertMap[_type] <> Invalid then
- return convertMap[_type](value)
- end if
- return value
-End function
-
-' RALE_getNodeByItem - Returns node field or child by item data
-' @param {dynamic} item - item data
-' @param {dynamic} node - type to which you want to convert
-' @return {dynamic} - node field or child
-Function RALE_getNodeByItem(item as Dynamic, node as Dynamic) as Dynamic
- itemType = type(item)
- if itemType <> "roAssociativeArray" then return Invalid
-
- nodeType = type(node)
- if nodeType <> "roSGNode" and nodeType <> "roArray" and nodeType <> "roAssociativeArray" then
- return Invalid
- end if
-
- if nodeType = "roSGNode" and item.child <> Invalid then
- index = FW_AsInteger(item.child)
- if index = 0 and FW_AsString(item.child) <> "0" then return Invalid
-
- return node.getChild(index)
- else if item.field <> Invalid then
- key = item.field
- if nodeType = "roSGNode" then
- if node.hasField(key) then
- return node.getField(key)
- else
- return Invalid
- end if
- else
- key = item.field
- if nodeType = "roArray" then
- key = FW_AsInteger(key)
- if key = 0 and FW_AsString(item.field) <> "0" then return Invalid
- end if
-
- return node[key]
- end if
- else
- return Invalid
- end if
-End function
-
-' RALE_getNodeByPath - Returns node by path
-' @param {object} root - root of nodes (main scene)
-' @param {array} path - path to node (for example [{ child: 1 }, { field: "fieldId" }])
-' @return {dynamic} - node or Invalid (if no node by this path)
-Function RALE_getNodeByPath(root as Dynamic, path as Object) as Dynamic
- node = root
-
- if type(path) <> "roArray" then return Invalid
-
- for each item in path
- node = RALE_getNodeByItem(item, node)
- if node = Invalid then return Invalid
- end for
-
- return node
-End function
-
-' RALE_getNodeIndex - Returns node index
-' @param {object} node - node
-' @param {object} parent - node parent
-' @return {integer} - node index
-Function RALE_getNodeIndex(node, parent) as Integer
- for i = 0 to parent.getchildCount() - 1
- if parent.getChild(i).isSameNode(node) then return i
- end for
- return -1
-End Function
-
-' RALE_getNodePath - Returns node path
-' @param {object} node - node
-' @param {object} root - root
-' @return {array} - node path
-Function RALE_getNodePath(node, root) as Object
- path = []
-
- if node <> Invalid and root <> Invalid then
- parent = node.getParent()
- while parent <> Invalid
- index = RALE_getNodeIndex(node, parent)
- if index = -1 then exit while
-
- node = parent
- parent = node.getParent()
-
- path.unshift({ child: index })
-
- if root.isSameNode(node) then exit while
- end while
- end if
- return path
-End Function
-
-' RALE_getNodeListByPath - Returns node by path
-' @param {object} root - root of nodes (main scene)
-' @param {array} path - path to node (for example [{ child: 1 }, { field: "fieldId" }])
-' @return {dynamic} - list of nodes (parent nodes and selected one) or Invalid (if no node by this path)
-Function RALE_getNodeListByPath(root as Dynamic, path as Object) as Dynamic
- node = root
- nodeList = [node]
-
- if type(path) <> "roArray" then return Invalid
-
- for each item in path
- node = RALE_getNodeByItem(item, node)
- if node = Invalid then return Invalid
- nodeList.push(node)
- end for
-
- return nodeList
-End function
-
-' RALE_getNodeIndexByPath - Returns node index or id by path
-' @param {array} path - path to node (for example [{ child: 1 }, { field: "fieldId" }])
-' @return {dynamic} - node index or id or Invalid (if no node by this path)
-Function RALE_getNodeIndexByPath(path) as Dynamic
- if type(path) <> "roArray" then return Invalid
-
- length = path.count()
- if length = 0 then return ""
-
- index = path[length - 1]
-
- if type(index) <> "roAssociativeArray" then return Invalid
-
- if index.child <> Invalid then
- index = index.child
- else if index.field <> Invalid then
- index = index.field
- else
- return Invalid
- end if
-
- return index
-End function
-
-' RALE_splitStringByLength - Splits string on parts and store in array
-' @param {string} str - string which will be splitted
-' @param {integer} length - max part langth
-' @return {array} - splitted string
-Function RALE_splitStringByLength(str, length) as Dynamic
- list = []
- strLength = str.len()
- currentPosition = 0
-
- while currentPosition < strLength
- list.push(str.mid(currentPosition, length))
- currentPosition = currentPosition + length
- end while
-
- return list
-End function
-
-' RALE_forEachNode - Goes through all the children and call the callback function
-' @param {object} node - root node
-' @param {object} options - options
-' @param {function} callback - callback function that will be called for each node
-Function RALE_forEachChild(node, options, callback, storage) as Dynamic
- nodeType = type(node)
- maxLevel = 50
-
- if FW_IsInteger(options.maxLevel) then
- maxLevel = options.maxLevel
- end if
-
- if nodeType = "roSGNode" then
- level = 0
- stateStack = []
- stateObj = {
- index : 0
- node : node
- }
-
- childCount = node.getchildcount()
- while true
-
- if childCount > stateObj.index then
- childIndex = stateObj.index
- childNode = node.getchild(childIndex)
-
- stateObj.index++
-
- if childNode <> invalid then
- childCountTmp = childNode.getchildcount()
-
- parentObj = stateObj
- childObj = Invalid
-
- if childCountTmp > 0 and level < maxLevel then
- childCount = childCountTmp
- stateStack.push(stateObj)
- level++
-
- stateObj = {
- index : 0
- node : childNode
- }
- childObj = stateObj
-
- node = childNode
- end if
-
- result = callback(childNode, childIndex, parentObj, childObj, storage)
-
- if not result then
- exit while
- end if
- end if
- else if level > 0 then
- stateObj = stateStack.pop()
- level--
- node = stateObj.node
- childCount = stateObj.node.getchildcount()
- else
- exit while
- end if
- end while
- else
- return false
- end if
-
- return true
-End function
-
-' RALE_forEachRegistryField - Goes through all the roRegistry and call the callback function for each field
-' @param {function} callback - callback function that will be called for each field
-Function RALE_forEachRegistryField(callback, storage) as Dynamic
- Registry = CreateObject("roRegistry")
-
- for each section in Registry.GetSectionList()
- RegistrySection = CreateObject("roRegistrySection", section)
- for each key in RegistrySection.GetKeyList()
- callback(RegistrySection.Read(key), key, section, storage)
- end for
- end for
-End function
-
-' RALE_forEachRegistrySection - Goes through all the roRegistry and call the callback function for each section
-' @param {function} callback - callback function that will be called for each section
-Function RALE_forEachRegistrySection(callback, storage) as Dynamic
- Registry = CreateObject("roRegistry")
-
- for each section in Registry.GetSectionList()
- callback(CreateObject("roRegistrySection", section), section, storage)
- end for
-End function
-
-Function RALE_DebugLog(message as String)
- callCommand("UIThread_log", {
- message: message,
- status: "debug"
- })
-End Function
-
-Function RALE_InfoLog(message as String)
- callCommand("UIThread_log", {
- message: message,
- status: "info"
- })
-End Function
-
-Function RALE_WarningLog(message as String)
- callCommand("UIThread_log", {
- message: message,
- status: "warning"
- })
-End Function
-
-Function RALE_ErrorLog(message as String)
- callCommand("UIThread_log", {
- message: message,
- status: "error"
- })
-End Function
diff --git a/test-project/components/RALETrackerTask.xml b/test-project/components/RALETrackerTask.xml
deleted file mode 100644
index ee302f1..0000000
--- a/test-project/components/RALETrackerTask.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test-project/images/s.png b/test-project/images/s.png
deleted file mode 100644
index 94f29dd..0000000
Binary files a/test-project/images/s.png and /dev/null differ
diff --git a/test-project/images/so1.png b/test-project/images/so1.png
deleted file mode 100644
index cea82fa..0000000
Binary files a/test-project/images/so1.png and /dev/null differ
diff --git a/test-project/images/so2.png b/test-project/images/so2.png
deleted file mode 100644
index a2cd682..0000000
Binary files a/test-project/images/so2.png and /dev/null differ
diff --git a/test-project/images/so3.png b/test-project/images/so3.png
deleted file mode 100644
index 363f893..0000000
Binary files a/test-project/images/so3.png and /dev/null differ
diff --git a/test-project/manifest b/test-project/manifest
deleted file mode 100644
index deb1626..0000000
--- a/test-project/manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-title=Animated Poster Sample Project
-major_version=0
-minor_version=1
-build_version=1
-ui_resolutions=fhd
-rsg_version=1.2
diff --git a/test-project/package.json b/test-project/package.json
deleted file mode 100644
index 562c8bb..0000000
--- a/test-project/package.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "private": true,
- "dependencies": {
- "sl": "file:../"
- },
- "devDependencies": {
- "ropm": "^0.6.3"
- }
-}
diff --git a/test-project/source/main.brs b/test-project/source/main.brs
deleted file mode 100644
index dccc152..0000000
--- a/test-project/source/main.brs
+++ /dev/null
@@ -1,26 +0,0 @@
-sub Main(args as dynamic)
- InitScreen()
-end sub
-
-
-function InitScreen() as void
- screen = CreateObject("roSGScreen")
- m.port = CreateObject("roMessagePort")
- screen.setMessagePort(m.port)
-
- rootScene = screen.CreateScene("MainScene")
- rootScene.id = "ROOT"
-
- screen.show()
-
- while(true)
- msg = wait(0, m.port)
- msgType = type(msg)
-
- if msgType = "roSGScreenEvent"
- if msg.isScreenClosed()
- return
- end if
- end if
- end while
-end function