How to use debugger when simulating physics with SDL? - debugging

I would like to use the debugger but I have two problems
I am using SDL to create a graphics window, when I run my program in Debug mode I can no longer see what is going on in the window.
When you are simulating physics the time elapsed affects the behaviour of the program but when you are debugging the time elapsed and the code are no longer in sync so the program cannot behave normally. What strategies can I use to overcome this?

Redraw the window more frequently in the places that you want to debug, for example do one step code line to draw the line then next step line to redraw the window. Use 2 monitors so that debugger is in one and your program in the other. If you don't have 2 monitors then it will be a little inconvenient to debug but you can make your debugger window small and place it in one side of the screen and have your program running on the other side of the screen.
I must admit I don't know anything about simulating physics. If that's something where you use many threads and the order of execution matters between them then you can place breakpoints in each thread and then switching between threads you can step over and decide which thread and how far should progress. If that something within single thread then you may want to add a code which will be altering the time elapsed. Perhaps you could implement kind of simulator which would make sure the elapsed time in the given place of the code is as you would normally expect.

Related

What is the recommended frequency for UI changes?

I have a cocoa application window (NSWindow) which position on the screen should be updated frequently (depending on some calculation). As noticed in the documentation, UI changes should be made on the main thread:
void calculationThread()
{
while(true)
{
calculatePosition();
if(positionChanged)
{
dispatch_async(dispatch_get_main_queue(), ^{ setWindowPos(); });
}
}
}
void setWindowPos()
{
[window setFrame:_newFrame display:YES];
}
Now the problem I have is that the window movement is very slow and delayed. After making some profiling I see that the calculation process takes about 40mSec, meaning that I'm queueing up a backlog of UI updates 25 times a second.
I've read here that this might be faster than they can be processed and timer should be used to fire the changes every tenth of a second or so. But, wouldn't it be too slow for the human eye (I mean, in that case the movement wouldn't be delayed but would be lagged causing pretty much the same affect).
I will appreciate some knowledge sharing on this. Actually my main 2 questions are:
Are 25-30 UI updates per second really to much?
If yes, what is the recommended UI changes frequency?
The frequency at which a window can be moved around onscreen without problems will of course depend upon the speed of the user's machine, the video card they have, the size of the window, and probably a bunch of other factors. There is no single good answer to this. However, if you just drag a window around on your screen, you will notice that it can probably be moved very smoothly (unless your machine is very busy or very low on memory or something); I would not expect 25 times per second to produce a problem on a modern Mac. Not even close, in fact.
#RobNapier's points about Core Animation etc. are fine, but overstated I think; there is nothing inherently wrong with changing your UI using a timer or other periodic update if that is what you actually want to do. CoreAnimation is a toolkit for making some types of animation easier; using it is not required, and it is not suited to every problem. Similarly, if you want to make changes that are actually synched to screen refresh then CVDisplayLink is useful, but it doesn't really sound like that's what you want to do.
For your purposes, your basic approach seems fine, although I would suggest adding an NSDate check in order to skip updates if the previous update was less than, say, 1/60th of a second previous. After all, the calculation appears to take 40mSec on your machine, but it might be much faster on some other machine; you want to throttle your drawing to a reasonable rate just to be a good citizen.
So what is the problem, then? I suspect the issue might actually be your call [window setFrame:_newFrame display:YES]. If you look at Apple's docs for that method, they state "When YES the window sends a displayIfNeeded message down its view hierarchy, thus redrawing all views." Each time you call that method, then, you are not only moving your window (which I gather is your intention); you are redrawing all of the contents of the window, too, and that is slow. If you don't need to do that, then that is the overhead you need to eliminate. Call setFrameOrigin: or setFrameTopLeftPoint: instead (which make the semantics clear, that you are moving the window without resizing it or redrawing it), or perhaps just setFrame:display: passing NO instead of YES, and I'm guessing your performance problem will vanish.
If you do in fact need to redraw the window contents every time, then please edit the problem description to reflect that. In that case, the solution will have to involve profiling why your window drawing is slow, and figuring out ways to optimize that, which is an entirely different problem.
As you've discovered, you should never try to drive the UI from a tight loop. You should let the UI drive you. There are three primary tools for that.
For simple problems, AppKit is capable of moving windows around the screen. Just call [NSWindow setFrame:display:animate:]. You can override animationResizeTime: to modify the timing.
In many cases AppKit doesn't give enough control. In those case, the best tool is almost always Core Animation. You should tell the system using Core Animation how you where you want UI elements to wind up, and over what period and path, and let it do the work of getting them there. See the Core Animation Programming Guide for extensive documentation on how to use that. It focuses on animating CALayer, but the techniques are similar for NSWindow. You'll use [NSWindow setAnimations:] to add your animation. Look at the NSAnimatablePropertyContainer protocol (which NSWindow conforms to) for more information. For a simple sample project of animating NSWindow, see Just Say No from CIMGF.
In a few cases, you really do need to update the screen manually at the screen update frequency. I must stress how rare this situation is. In almost all cases, Core Animation is the correct tool. But in those rare case (some kinds of video for instance), you can use a CVDisplayLink to handle this. That will call you each time the screen would like to refresh, giving you an opportunity to update your content to match.

SFML - Frame independent movement + dragging window

I am trying to implement frame independent movement in SFML, but am having trouble getting it to work. When I had this problem earlier with SDL, I found somewhere that Windows pauses the main thread of an application whenever it is moved (by dragging the title-bar). The problem comes because when the window is being dragged, the clock updates but the movement is not drawn until I let go of the window. When I move the window, the window is no longer being drawn to, but the time is still increasing. Thus, when I let go of the window, the units immediately jump to where they would be if the window had not been dragged.
I tried thinking of a solution, and since Windows only pauses the main thread, I considered just running the entire game in a separate thread, and launching it in main() but that does not appear to work as the same result occurs. I also thought about the extremely low FPS's I get as a result, but I would have no way of being able to differentiate between someone dragging the window and if their game is just naturally running slowly... There has to be a way to either prevent windows from pausing the main thread, or doing something that prevents this issue, but I haven't found any sort of solution on the internet...
Here is a link to a zip file which demonstrates the problem. Both Demo0 and Demo1 are the same, except Demo1 uses a second thread to run the program, yet the same effect occurs. Just run both and watch as the delta value is output to command line. Then drag the window and move it to some other part of the screen. When you let go, you should see a very large delta value and the circle should jump ahead depending on how long you had the window suspended. The source code is all there (in the "src" folder), so I hope people can understand the exact problem: http://www.sendspace.com/file/4er8f4
I see two solutions to the problem:
You can try to see if the sf::Events LostFocus or Resized picks up a window drag, and if they do, simply pause the clock on the game. More information can be found here: http://www.sfml-dev.org/tutorials/2.0/window-events.php
However, if that doesn't work, I would simply add an upper-cap on your delta. Meaning, if the game goes above a certain threshold of delta (1/60 or 1/30), you set delta to a lower value. In your situation though, this cap could probably be really big, like 1/15.
if(delta > 1/15.0f)
delta = 1/15.0f;
Chances are you don't expect your game to be playable at 15fps anyways, and if the user drags the window while moving, the worst you'll have to deal with is a 15fps delta on resume.

InvalidateRect called too frequently blocks other windows from redrawing

I develop audio plugins, which are run inside their hosts and work realtime. Each plugin has its own window with controls, which often contains some kind of analysis pane, a pretty big rectangle that gets repeatedly painted (e.g. 20-50x per second). This is all working well.
The trouble comes when the user adjusts a parameter - the plugin uses WM_MOUSEMOVE to track mouse movements and on each change calls ::InvalidateRect to make the relevant portion of the window be redrawn. If you move quickly enough, the window really gets quickly repainted, however there seems no time for the host and other windows to be redrawn and these usually perform some kind of analysis feedback too, so it is really not ideal.
No my questions:
1) Assuming the host and other window are using ::InvalidateRect too, why mine is prioritized?
2) How to make ::InvalidateRect not prioritized, meaning the window needs to be invalidated, but it may be later, the rest of the system must get time for their redrawing too.
Thanks in advance!

How to diagnose an unexpected delay during dragging?

From time to time, one of my apps experiences a delay of 2-10sec whilst dragging an object in a complex view. In some cases, the delay is sufficient to cause the wait cursor (spinning pizza of death) to appear.
Time Profiler reveals nothing very remarkable -- just the expected drawing calls to update the view as the object is dragged. (This is a lot of computation, but I see no obvious difference in the profile during pauses and between pauses.)
Memory profiler reveals nothing special about the pauses. Allocation seems flat throughout the drag. Leaks is clean. (My initial assumption was that I was spinning off too many autoreleased objects, but that doesn't seem to be the issue.)
Activity Monitor indicates that during the drag I'm pretty much using up one core for all the redrawing. That's what I expect.
Any ideas of where to look next?
Hmm. Well maybe you could try running Instruments.app with 'Record Waiting Threads' enabled. This will show you where the code is waiting as well as running. You might be sitting in a semaphore or doing some IO- that will show up in this mode.

Bring form on top of others when clicked on taskbar button in Delphi

Base question: TStatusBar flickers when calling Update procedure. Ways to painlessly fix this
The executed code is in the questions first posts first part ( you can see light grey separating line ) ...
But - problem is that while this code is executed, form does not automatically activate and focus on the top of all other applications.
I have read these articles:
http://www.installationexcellence.com/articles/VistaWithDelphi/Original/Index.html
http://delphi.about.com/od/formsdialogs/l/aa073101b.htm
but according to them it should be working no matter what. I tried all the TApplicationEvents and TForm events with Show; Visible: Repaint; Refresh; BringToFront; ... nothing works.
So - I think I have two options - multithreading or trapping WM_SYSCOMMAND message and in the SC_ACTIVE event simply repaint form. Could this scenario become successful?
None of your linked articles deal with the problem you are having. What you see is the behaviour of a program that does not process Windows messages, so consequently it will not redraw parts that become invalid, and it will not react to keyboard or mouse input (for example moving or resizing with the mouse, or app activation using the taskbar button).
In your code you call StatusBar1.Update, so at least the status bar text is redrawn, but apart from coming to the foreground your application is probably also ignoring move or resize requests.
You need to process Windows messages in a timely manner, so any execution path that takes more than say 200 or 300 milliseconds needs to make sure that messages are handled, otherwise the application will appear unresponsive or hung.
You have basically three options:
Keep the long running code, and insert calls to Application.ProcessMessages - this will allow Windows messages to be processed. Make sure that you keep the code from being entered again, for instance by disabling all the controls that are used to start the operation.
Rework your code in a way that it appears as a sequence of steps, each taking no more than a few 10 milliseconds. Put calls to the code in a timer event handler, or call it from the Application.OnIdle handler.
Call your code in a worker thread, and post messages to the main GUI thread to update your UI.
All these options have their own pros and cons, and for multithreading especially there is a lot of questions and answers already here on SO. It is the most difficult but best option overall when you are working on anything more than a toy program.

Resources