Graphics

 View Only
  • 1.  Scripting For Loop Issue

    Posted 07-12-2022 13:09
    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 xpBaseTakeItem
    dim fb as xpOutputFrameBuffer
    dim layer as integer
    
    engine.GetOutputFrameBuffer(0,fb)
    for layer = -99 to 99
    fb.GetTakeItemOnLayer(layer,takeitem)
    if takeitem.IsOnline() then
    takeitem.Execute
    end if
    next​

    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
    ------------------------------


  • 2.  RE: Scripting For Loop Issue

    Ross Staff
    Posted 07-15-2022 05:57
    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
    ------------------------------



  • 3.  RE: Scripting For Loop Issue

    Posted 07-15-2022 09:48
    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
    ------------------------------



  • 4.  RE: Scripting For Loop Issue

    Ross Staff
    Posted 07-17-2022 21:42
    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 xpOutputFrameBuffer
    engine.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 if
    next​


    ------------------------------
    Greg Pray
    Senior XPression Broadcast Manager
    Ross Production Services
    ------------------------------



  • 5.  RE: Scripting For Loop Issue

    Posted 07-17-2022 22:29
    Ah that makes perfect sense as to why it was failing out, didn't realize the test ended if no value was found on the first loop. Thanks so much! When we update to v10, I will take a look at that other method.

    Thanks again!

    ------------------------------
    Jack Reynolds
    ------------------------------



  • 6.  RE: Scripting For Loop Issue

    Ross Staff
    Posted 07-18-2022 08:40
    I like that second option, didn't know that was a thing, thanks Greg!

    ------------------------------
    Simon Redmile
    Senior Graphic Programmer & Designer
    Ross Video
    Bristol United Kingdom
    ------------------------------



  • 7.  RE: Scripting For Loop Issue

    Posted 08-06-2022 16:54
    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 xpBaseTakeItem
    dim fb as xpOutputFrameBuffer
    dim layer as integer
    
    'FB4
    engine.GetOutputFrameBuffer(3,fb)
    for layer = -99 to 99
    	if fb.GetTakeItemOnLayer(layer,takeitem) then
    			while takeitem.IsOnline()
    			takeitem.Execute
    			end while
    	end if
    next​

    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
    ------------------------------



  • 8.  RE: Scripting For Loop Issue

    Ross Staff
    Posted 08-08-2022 14:20
    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
    ------------------------------



  • 9.  RE: Scripting For Loop Issue

    Posted 08-08-2022 22:36
    Hi Greg,

    I appreciate that response. I agree that the take offline function is the solution to this issue. Unfortunately, this graphics package is a hot mess of inconsistencies, with only certain graphics having proper transition logic in them. I appreciate your help nonetheless, and that script does definitely work on the graphics with transition logic in them. For now though, given the state of this project, I think it is safer to use the earlier script that you helped with, and just have the operator spam the key until it pushes fully through.

    Thank you nonetheless for your help!

    ------------------------------
    Jack Reynolds
    ------------------------------



  • 10.  RE: Scripting For Loop Issue

    Posted 08-10-2022 08:25
    Communication is critical in software development https://mlsdev.com/services/it-staff-augmentation. While technical skills have a direct impact on the work of software engineers, soft skills have a broader effect on the overall success of a company. Effective communication is a crucial part of any software engineer's job, from junior to senior. For this reason, a software engineer must be able to communicate effectively with their teammates. Effective communication is vital to the success of a company, as it facilitates the work of software engineers.

    ------------------------------
    Nick Miles
    Engineer
    naza
    ------------------------------