Scripts run instantaneously, which means that your while loop is always going to find that the take item is still online. From the perspective of the script, no time is passing, so it just runs forever and causes the crash.
If the goal is to have a keyboard shortcut that always animates off everything on the channel no matter what, you'll probably need to use transition logic and separate your offline animations into their own scene directors. When using pauses, XPression doesn't distinguish the difference between a pause waiting for a highlight animation vs a pause waiting for an offline animation. With transition logic, you could make uses of xpTakeItem.setOffline to reliably animate off regardless of where the graphic is within a sequence of pauses, whereas xpTakeItem.execute can only advance the pauses.
That said, I typically use a script like the below to "resume" channels -- if items are paused, it advances them, but if they're finished, it takes them offline. An actual "Resume Channel" function is available in the regular keyboard shortcuts menu under "Channel Functions" in the Available Global Functions list -- that one only advances pauses.
dim fb as xpOutputFrameBuffer
engine.getOutputFrameBuffer(0,fb)
for i as integer = -99 to 99
dim take as xpTakeItem
if fb.getTakeItemOnLayer(i,take) then
'4 means paused
if take.state = 4 then
take.execute
else
take.setOffline
end if
end if
next
------------------------------
Greg Pray
Senior XPression Broadcast Manager
Ross Production Services
------------------------------
Original Message:
Sent: 08-06-2022 16:53
From: Jack Reynolds
Subject: Scripting For Loop Issue
Thank you again for your help. While working with this script I have noticed that if there is a pause in the scene, then I have to keep running the script to make it completely work (which is exactly how it is written to work). For example:
Execute to effect online
Execute to push the pause (to highlight a line or morph the graphic, etc)
Execute to effect offline
I have been able to partially remedy this with a for loop that sends an execute command a bunch of times, but I do not like the inconsistency of how it works. Therefore, I want it to do a loop to continue pressing execute while the take item is online.
dim takeitem as xpBaseTakeItemdim fb as xpOutputFrameBufferdim layer as integer'FB4engine.GetOutputFrameBuffer(3,fb)for layer = -99 to 99 if fb.GetTakeItemOnLayer(layer,takeitem) then while takeitem.IsOnline() takeitem.Execute end while end ifnext
As currently written, it does continue to push through a graphic until it is off, however it seemingly never exits the while loop and crashes XPression. I've tried some different variations of it and cannot get it to work. Any ideas what is wrong with my logic?
Thank you!!
------------------------------
Jack Reynolds
Original Message:
Sent: 07-17-2022 21:42
From: Greg Pray
Subject: Scripting For Loop Issue
The script is failing when it tries to get a take item on an empty layer -- in this case, once it fails to find a take item on layer -99, it stops running, so an item on any other layer in the loop won't be evaluated.
This can be easily fixed by nesting another if-then statement to evaluate if an item was found on the layer or not. The xpOutputFrameBuffer.getTakeItemOnLayer method, like most of the other "get" methods, returns true/false values. So the fix would be:
if fb.GetTakeItemOnLayer(layer,takeitem) then if takeitem.IsOnline() then takeitem.Execute end if end if
You may also be interested in xpOutputFrameBuffer.getTakeItem, added in version 10, which simply gets online take items by index rather than layer. That way you don't have to loop through 200 layers, and it will never fail because it's always getting items that are already online. For example:
dim fb as xpOutputFrameBufferengine.getOutputFrameBuffer(0,fb)dim take as xpTakeItem'UsedLayerCount returns how many items are online (-1 because the index starts at 0)for i as integer = 0 to fb.usedLayerCount - 1 fb.getTakeItem(i,take) if take.isOnline then take.execute end ifnext
------------------------------
Greg Pray
Senior XPression Broadcast Manager
Ross Production Services
Original Message:
Sent: 07-15-2022 09:48
From: Jack Reynolds
Subject: Scripting For Loop Issue
Sorry, I should have clarified. In this project, execute once to take on, execute again to take off. We do not use any take offline or separate functions to animate off.
------------------------------
Jack Reynolds
Original Message:
Sent: 07-15-2022 05:56
From: Simon Redmile
Subject: Scripting For Loop Issue
Surely if you are finding them online then execute doesn't do anything as they are already online?
------------------------------
Simon Redmile
Senior Graphic Programmer & Designer
Ross Video
Bristol United Kingdom
Original Message:
Sent: 07-12-2022 13:09
From: Jack Reynolds
Subject: Scripting For Loop Issue
Hello,
I am trying to create a small script that does the following:
On Key Press:
1. Look at a particular framebuffer.
2. Get the takeID of items on layers -99 to 99.
3. Execute for layers that have something on them.
The script I wrote is as follows:
Sub OnKeyPress (Engine as xpEngine)dim takeitem as xpBaseTakeItemdim fb as xpOutputFrameBufferdim layer as integerengine.GetOutputFrameBuffer(0,fb)for layer = -99 to 99fb.GetTakeItemOnLayer(layer,takeitem)if takeitem.IsOnline() thentakeitem.Executeend ifnext
The script does not do anything if the for loop is active. When I comment out the for loop, it works perfectly for anything on layer 0. Any help on this would be appreciated.
Thanks!
------------------------------
Jack Reynolds
------------------------------