Animation no go in 64 bit compile

I have an Animated Sort app that animates how 12 different sorting algorithms sort an array of numbers where bars represent the numbers and move as the array elements are moved during the sorting process.

The original program did all of its drawing straight to the canvas graphics object. A couple years back this was modified to work with a picture object which is painted during the canvas paint event.

This all works great when compiled for 32 bit. When I compile it for 64 bit no animation takes place. The bars all sit as originally painted until the sort is completed and then the final result of the sorted bars appears. It has me thoroughly puzzled. I don’t do near the programming that I used to but I figured that this conversion would simply be changing build architecture popup menu in the MacOS Build settings from 32bit to 64 bit and then do a build and all would now be running in 64 bit.

In any of the sorting methods whenever two elements of the array are going to be swapped the doSwap method of the window is called and the code for them method looks like the following:

[code]doSwap(bar1 as Integer, bar2 as Integer)
Dim temp as Integer

#pragma BackgroundTasks False
#pragma BoundsChecking False
// Swapping values in the i and j cells of the barsToSort array
temp = barsToSort(bar1)
barsToSort(bar1) = barsToSort(bar2)
barsToSort(bar2) = temp

numberOfSwaps = numberOfSwaps + 1 // boost swap count for this sort
if doAnimation then // bypass if no animation running
drawOneBar(bar1) // redraw first bar
drawOneBar(bar2) // redraw the second bar
end if[/code]

The drawOneBar method has the following code.

[code]drawOneBar(theBar as Integer)
Dim inc, xPos, yPos, yPosFull as Integer

#pragma BackgroundTasks False
#pragma BoundsChecking False
if doAnimation then // bypass if no animation running
inc = barWidth + spaceBetweenBars // width of bar and spacing
xPos = 3 + (theBar - 1) * inc // x pos for this bar
yPos = Canvas1.height - 1 - maxBarHeight // y pos for max bar height
yPosFull = yPos
sortPic.Graphics.foreColor = bkgndColor // set to bg color
sortPic.Graphics.fillRect xPos, yPos, barWidth, maxBarHeight // blank out any old bar with background color
yPos = Canvas1.height - 1 - barsToSort(theBar) // y position for new bar height
sortPic.Graphics.foreColor = barColor
sortPic.Graphics.fillRect xPos, yPos, barWidth, barsToSort(theBar) // draw new bar
canvas1.RefreshRect(xPos, yPosFull, barWidth, maxBarheight, False)
end if[/code]

The above, exactly as shown, works beautiful in 32 bit. In 64 bit I have tried with, and without, the #pragma statements with no change in execution. No animation takes place. Also, if multiple sort algorithms are chosen, the original bars are not re-shown after each sort finishes like they are in 32 bit.

Any suggestions on what is needed to get his working in 64 bit will be most appreciated. I guess this is what I get for thinking the conversion would be a simple click and recompile.

I should add that the Canvas1.Paint event has the single line of code:

g.DrawPicture(sortPic, 0, 0)

How are you doing the animation? Are you using a thread or timer?

Canvas based animations in 64-Bit Xojo application are possible, if you look at http://machdr.com the animated controls are basically canvas classes, which use a timer to handle the frame updates.

I had a similar issue with a recent application. I commented out the #pragma Backgroundtasks False…

and everything worked perfectly.

Sam: No thread, no timer, never needed either in 32-bit. The canvas1.refreshrect( ) seemed to do the job then.

Matherw: I thought that I had tried commenting out the #pragma statements; but, will have to double check and see if my memory is failing me. Am one of the old timers on this list.

Commented out every #pragma statement in the program and there is still no animation. This sure was easy to accomplish back in the RealBasic days. In fact the very first version was in FutureBasic.

Wait, so somehow you magically got animation without controlling the redraw rate? You should at least be controlling it with a timer of some sort that tells the canvas to display Z frame Y time after displaying X frame.

it looks like it animates a sort process… so the swapping of the values is what controls the “animation”
so it could be

  • its now “too fast” (doubtful)
  • a bug in refreshrect (possible)
  • or 64bit graphics is totally “frelled”

question I have… is do you end up seeing the “starting” frame? or the “ending” frame?

I don’t see anything that determines frame display time, and there’s no mention of anything to that measure in the description of how this functions. The frames need to sit on screen long enough to be seen to become an animation. If it’s just a loops with no time delay it’s just drawing the frames as quick as it can. This method and RefreshRect might just be working too fast for the computer to display.

Have you tried stepping through it in the debugger?

RefreshRect used to force a screen update instantly, which is how it has worked in the past. “Invalidate” would mark an area of a view as ‘dirty’ and then when the current method completes, the window server would ask the ‘dirty’ views to redraw.

I wouldn’t be surprised if refreshRect either no longer works like it used to, or perhaps it never worked this way in 64-Bit. Either way I would suggest considering an alternative animation solution.

An oversimplified version is to use a timer. When you want to animate, you store the object, start value, end value, startTime and duration for the animation. You set the timer’s period based upon 1000 / framesPerSecond ( 30 fps is 33 ).

In the action event you calculate how far into the animation the current time is, then use that to calculate the correct values for the object, update the object (and canvas, use invalidate( left, top, width, height)).

Once your currentTime exceeds startTime + duration, your animation is over and you can stop the timer.

Edit: Just want to add that a lot of functions in the recent macOS versions has to be ‘scheduled’ nowadays, I believe this is because of triple buffering.

Can you post an example project so that we can try this?

Dave
In the very beginning I see the randomly sized bars. Once the animate button is clicked the next thing that I see is the finished product. The app allows from 1 to 12 of the sort algorithms to be selected. If I choose more than one I should, as under 32 bit, see the animation of the first algorithm along with the name of the algorithm such as shell. When it finishes I should see the bars set back to there original positions in preparation for the next sort algorithm and then see the animation process for this next sort. This should repeat for each of the selected sort algorithms. Under 64 bit I see the very beginning and at the end of the first sort I see the sorted bars and then no change until however many sorts selected have finished processing.

It is like it is never allowing the refreshes to be executed like it does in 32 bit mode.

Seeing this I decided to change over to the non-animated version of the program. This program has the same 12 sort algorithms and again you can choose from 1 to 12 of them to run when the start button is clicked. In this program as each sort completes the information for that algorithm is written in to a line of a list box, showing compares made, swaps made, and time elapsed. But HERE AGAIN IN 64 BIT MODE NON OF THE STATS APPEAR UNTIL ALL OF THE SORTS ARE COMPLETED. In 33 bit mode the lines fill, one by one as each sort completes. This is not a speed thing as the program allows the selection of different array sizes from 1000 elements to 1,000,000 elements.

I am about to add programming to my retirement as this is ridiculous.

It just seems that 64 bits is not allowing the refreshes to take their turn in either the program doing the animation or the program simply showing the stats for a given sort in a listbox.

You never specified: is the 32 bit app Carbon or Cocoa?

Michael, the 32 bit version Cocoa as it is compiled with the latest version of Xojo and was modified not too long ago to do its work with a picture object with the graphic object on the window painting the picture when it’s Paint event is invoked. The animation is moving the bars on the picture object that represent the array elements. Choose to compile in 32 bit and it runs beautifully. Choose to compile in 64 bit and no animation occurs.

A loop like this doesn’t yield time to the main event loop so that the redraws CAN take place
And drawing happens on the main event loop

Try UpdateNow
http://documentation.xojo.com/index.php/Window.UpdateNow

@Harrie Westphal ,
Don’t get discouraged. Take a break and then spend some time trying to understand how to implement time based animation. It’s not that difficult, just requires retraining your mind a little bit.

If you and others are interested, I’ll write a tutorial for the xDev magazine.

Not being a professional Xojo programmer and not having a web site where I can post a small sample of this project for others to look at I posted it to Feedback and included a small sample project that only does a comb sort, a good fast sort. To me this problem seems to be that Xojo is not yielding any time for background processes at loop boundaries in 64 bitlike it does in 32 bit. If that is true than hopefully the Xojo folks can remedy my problem. If I am wrong in that assumption hopefully one of you good folks can come up with a remedy. I tried Norman’s suggestion of using the Window.UpdateNow method and it changed nothing; however, that may totally be my not setting everything correctly. I turned on implicit instance for the window as the UpdateNow mentions.

The feedback number is 49889 and is titled: animation that works in 32bit MacOS does not work in 64 bit MacOA

Yes, I failed to catch the mistype of MacOS at the end of the title. Me bad

I don’t see any animation with 32bit on Xojo 2017r1/High Sierra.

I’ve looked at the sample
As I suspected the loop to run the sort completely blocks the main event loop of the app
And ALL UI drawing goes through the main event loop

It really needs to be split out into a timer that draws one frame at a time or a thread that redraws one frame at a time via a timer
Or some other way that yields time back to the main thread so each frame of the animation can be drawn

I’ve added such a sample to the case for you to peruse
It basically lifts the “for loop” out and uses a repeatedly firing timer to run the for loop that did the sort