I've built an application that connects CasparCG (a video and graphics playback engine for broadcasting) with LiveXML, which outputs data from scoreboards at sporting events. For several years, I have had the same code, which has worked perfectly within LiveCode during broadcasts (and still does). Recently, I exported my app for Windows and Mac so that others can use it. However, the button that automates the scoreboard graphics on screen does not work in the exported versions for either OS. When I reopen LC and run it there, everything is fine. I am at a loss as to what I should do, or what might be causing this.
Here's the basic workflow:
- LiveXML collects scoreboard data from the game site and deposits it in an XML file on my desktop.
- My application reads the XML file every 100 milliseconds. It puts all existing data into variables, and then checks to see if the new information from the game is different. If not, it ignores the new data. If so, it triggers buttons in the application to update the graphics on screen with the new data, as if a person had done it with a mouseclick. That way I can trigger animations as the data is updated.
- Besides seeing the clock moving, I can tell when it's working because there's a large amount of activity on my CasparCG server, which I can see.
Instead of running every 100 milliseconds, the button on the finished app appears to only run once, and then never again. Here's the code:
Code: Select all
global tVscoreholder
global tHscoreholder
global tHtimeoutsholder
global tVtimeoutsholder
global tHTOGraphicholder
global tVTOGraphicholder
global tQuarterholder
global tDownholder
global tDownonlyholder
global tDistanceholder
on mouseUp
if backgroundcolor of button "Automate Countdown" is red then
send mouseUp to button "Automate Countdown"
end if
if label of me is "Automate Scorebug" then
set label of me to "Stop Automation"
set the backgroundcolor of me to red
put field T1Score into tVscoreholder
put field T2Score into tHscoreholder
loadXML
else
set the label of me to "Automate Scorebug"
set the backgroundcolor of me to green
end if
end mouseUp
command loadXML
if label of me is "Stop Automation" then
local tTree
put readToXMLTree() into tTree
if tTree is empty then
wait 1 second with messages
put readToXMLTree() into tTree
end if
processXMLTree tTree
revXMLDeleteTree Tree
send "loadXML" to me in .1 seconds
else if label of me is "Automate Scorebug" then
exit to top
end if
end loadXML
private function readToXMLTree
set the itemdelimiter to slash
set the itemdelimiter to comma
local tXMLData, tResult
put field "xmlfile" into xmlFileName
put url("file:" & specialFolderPath("desktop") & slash & xmlFileName & ".xml") into tXMLData
put the result into tResult
if tResult is not empty then
put cr & the date && "-" && the time & ":" & cr & "Error: " && tXMLFile before field "errorfield"
wait 1 second with messages
return empty
send "loadXML" to me
end if
local tTree
put revXMLCreateTree(tXMLData, false,true,false) into tTree
if tTree is not an integer then
put cr & the date && "-" && the time & ":" & cr & "Error: " && tTree before field "errorfield"
wait 1 second with messages
return empty
send "loadXML" to me
end if
return tTree
end readToXMLTree
private command processXMLTree pTree
local tClock
put revXMLNodeContents(pTree, "info/clock") into tClock
put revXMLNodeContents(pTree, "info/shotclock") into tShotclock
put revXMLNodeContents(pTree, "info/Hscore") into tHscore
put revXMLNodeContents(pTree, "info/Vscore") into tVscore
put revXMLNodeContents(pTree, "info/quarter") into tQuarter
put revXMLNodeContents(pTree, "info/Htimeouts") into tHtimeouts
put revXMLNodeContents(pTree, "info/Vtimeouts") into tVtimeouts
put revXMLNodeContents(pTree, "info/HTOGraphic") into tHTOGraphic
put revXMLNodeContents(pTree, "info/VTOGraphic") into tVTOGraphic
put revXMLNodeContents(pTree, "info/down") into tDown
put revXMLNodeContents(pTree, "info/togo") into tTogo
put "cg" && field "CasparCGChannel" &&" update 1" into s1xml
put quote after s1xml
put "<templateData>" after s1xml
###CLOCK###
put "<componentData id=\" after s1xml
put quote after s1xml
put "gameclock\" after s1xml
put quote after s1xml
put "><data id=\" after s1xml
put quote after s1xml
put "text\" after s1xml
put quote after s1xml
put " value=\" after s1xml
put quote after s1xml
put tClock after s1xml
put tClock into field "DataFeedClock"
put "\" after s1xml
put quote after s1xml
put " /></componentData>" after s1xml
###SCORE###
if tHscore <> tHscoreholder then
put tHscore - tHscoreholder into scoreAmt
put "Team2plus"& scoreAmt into buttonSend
if exists(button buttonSend) then
send mouseDown to button buttonSend
send mouseUp to button buttonSend
else
put tHscore into field T2Score
send textchanged to field T2Score
end if
put tHscore into tHscoreholder
end if
if tVscore <> tVscoreholder then
put tVscore - tVscoreholder into scoreAmt
put "Team1plus"& scoreAmt into buttonSend
if exists(button buttonSend) then
send mouseDown to button buttonSend
send mouseUp to button buttonSend
else
put tVscore into field T1Score
send textchanged to field T1Score
end if
put tVscore into tVscoreholder
end if
####TIMEOUTS####
if tHtimeouts <> tHtimeoutsholder then
if tHtimeoutsholder is "Hide" then
else
send mousedown to button "t2to"
set the label of button "t2to" to tHtimeouts
send mouseup to button "t2to"
put tHtimeouts into tHtimeoutsholder
end if
end if
if tVtimeouts <> tVtimeoutsholder then
if tVtimeoutsholder is "Hide" then
else
send mousedown to button "t1to"
set the label of button "t1to" to tVtimeouts
send mouseup to button "t1to"
put tVtimeouts into tVtimeoutsholder
end if
end if
#### QUARTER ####
if tQuarter <> tQuarterholder then
put "<componentData id=\" after s1xml
put quote after s1xml
put "quarter\" after s1xml
put quote after s1xml
put "><data id=\" after s1xml
put quote after s1xml
put "text\" after s1xml
put quote after s1xml
put " value=\" after s1xml
put quote after s1xml
if tQuarter is "1" then
put tQuarter & "st" into tQuarteredit
put tQuarteredit after s1xml
else if tQuarter is "2" then
put tQuarter & "nd" into tQuarteredit
put tQuarteredit after s1xml
else if tQuarter is "3" then
put tQuarter & "rd" into tQuarteredit
put tQuarteredit after s1xml
else if tQuarter is "4" then
put tQuarter & "th" into tQuarteredit
put tQuarteredit after s1xml
else if tQuarter is "5" then
put "OT" into tQuarteredit
else if tQuarter is "6" then
put "2OT" into tQuarteredit
else if tQuarter is "7" then
put "3OT" into tQuarteredit
else if tQuarter is "8" then
put "4OT" into tQuarteredit
end if
set the label of button "quarter" to tQuarteredit
if tQuarteredit is "1st" then
set label of button "QuarterSelector" to "End of 1st Quarter"
end if
if tQuarteredit is "2nd" then
set label of button "QuarterSelector" to "Halftime"
end if
if tQuarteredit is "3rd" then
set label of button "QuarterSelector" to "End of 3rd Quarter"
end if
if tQuarteredit is "4th" then
set label of button "QuarterSelector" to "Final"
end if
if tQuarteredit is "OT" then
set label of button "QuarterSelector" to "OT"
end if
put "\" after s1xml
put quote after s1xml
put " /></componentData>" after s1xml
put tQuarter into tQuarterholder
end if
### DOWN AND DISTANCE ###
write invokexml & format("\r\n") to socket server
if tDown && "&" && tTogo <> tDownholder then
put field IP after server
put "cg" && field "CasparCGChannel" && "invoke" && field "ScorebugFlashLayer" && quote & "removedowndistanceholder" "e into invokexml
write invokexml & format("\r\n") to socket server
if tDown <> tDownonlyholder then
end if
if the hilite of button "autodowndistance" is true then
put label of button "downdistanceinterval" into downdistanceinterval
send mousedown to button "downdistance" in downdistanceinterval seconds
end if
if tDown is "1" then
put "1st" into tDownedit
else if tDown is "2" then
put "2nd" into tDownedit
else if tDown is "3" then
put "3rd" into tDownedit
else if tDown is "4" then
put "4th" into tDownedit
end if
set the label of button "down" to tDownedit
put tTogo into field "distance"
set the label of button "downdistance" to "Show Down and Distance"
set the backgroundcolor of button downdistance to gray
put tDown into tDownonlyholder
put tDown && "&" && tTogo into tDownholder
put "cg" && field "CasparCGChannel" && "update" && field "ScorebugFlashLayer" into ddxml
put quote after ddxml
put "<templateData>"after ddxml
put "<componentData id=\" after ddxml
put quote after ddxml
put "downdistanceholder\" after ddxml
put quote after ddxml
put "><data id=\" after ddxml
put quote after ddxml
put "text\" after ddxml
put quote after ddxml
put " value=\" after ddxml
put quote after ddxml
put label of button "down" && "and" && field "distance" after ddxml
put "\" after ddxml
put quote after ddxml
put " /></componentData></templateData>" after ddxml
put quote after ddxml
write ddxml & format("\r\n") to socket server
end if
put "</templateData>" after s1xml
put quote after s1xml
put field IP after server
write s1xml & format("\r\n") to socket server
if tDown is empty then
put field IP after server
put "cg" && field "CasparCGChannel" && "invoke" && field "ScorebugFlashLayer" && quote & "removedowndistanceholder" "e into invokexml
end if
if tTogo is empty then
put field IP after server
put "cg" && field "CasparCGChannel" && "invoke" && field "ScorebugFlashLayer" && quote & "removedowndistanceholder" "e into invokexml
write invokexml & format("\r\n") to socket server
end if
end processXMLTree
end readToXMLTree