How can I refresh core plot without returning from a method? - cocoa

I have a cocoa interface that uses core plot. When I press a button in the interface, a plot is drawn. I wanted to create a sequence of graphs by calling the plotting method multiple times along with calls to sleep() in between. But it seems that even though the call to reload data is made that nothing happens until the function exits(only showing last graph as well). Now I know that CPAnimation exists but before I start using it I was wondering what it is that happens when the function exits that makes the graph refresh. Would I have to yield to the thread that takes care of the refreshing instead of using sleep?

Ok I figured out how. I called the reloadData method from a method in a separate thread (which always returns). This boiled down to calling reloadData from an IBAction and also with an NSTimer. Finally instead of using sleep I will use NSConditionLock coordinate the processing and the refreshing

Presumably, Core Plot (or your code) sets the view as needing display. That doesn't happen immediately; it happens when you return to the event loop.
Whenever you use sleep in a Mac OS X application, you kill a puppy. Use NSTimer instead. Have your timer callback method do the work required for one graph, and set whatever instance variables are necessary for your the method to know which graph it should draw, so that the method draws each graph in turn until it runs out of them.
Or, better yet, present a list of graphs that the user can choose from, instead of making the user watch all the graphs as a slide-show. (Unless an explicitly-labeled slide-show is what you're implementing.)

Core Plot, like most Cocoa drawing frameworks, is lazy: it draws at the end of the run loop iteration. This is to ensure that things aren't drawn too often.
Rather than drawing immediately, the layers are marked as needing drawing.
As was pointed out by others, a better approach to sleeping is to use NSTimer to avoid blocking the run loop, or to use NSObject methods like performSelector:withObject:afterDelay:

Peter has it right—the reload data method doesn't actually draw anything. The plot is marked as needing display and refreshed the next time the layers are drawn to the screen. If you use sleep, it never gets a chance to draw.
Also note that Core Plot is a fairly young project; CPAnimation and the related classes are stubs. They don't really do anything yet. :-)

Related

what is the best approach to scheduling repaint for winapi window?

I already tried multiple ways of rendering simple animations on winapi windows using wingdi, and realized that its fairly slow even for primitive animations, and inconsistent if i do it by spamming SendMessageW when there are no events for this window. So I thought that instead of rendering when I can i should schedule it with a fixed interval hence improving framerate and quality of the animation. I now wondering if this can be done with registering some callback with windows or there is no such functionality and i do have to spin another thread to function as a timer? Is it generally a better idea? What is the commonly accepted way to do things like this, when event triggered redraws just wont cut it?
Concerning the scheduled animations, there is SetTimer() and KillTimer(), if I remember their names correctly. In any case, "timer" is what you're looking for.
Concerning the painting in the timer callbacks, don't. Instead, adjust animation parameters (positions, colours etc) and trigger a redraw using InvalidateRect(). This will in turn invoke the regular drawing event handler. The difference is that this will not waste any CPU if your window is hidden or minimized. Also, in any case, when the window is un-hidden, the drawing event handler has to be able to draw the right window content anyway.
There is a derived version of this where you update an image in a memory DC and only blit to the window in the drawing event handler. It's unclear whether that is necessary in your case though. It's only when drawing takes an extended amount of time and you want to keep your UI responsive.
Well as my luck usually goes i found this article on MSDN, and it has a very nice example. Putting it here if someone will have same question

Updating contents of multiple NSTextView objects in a single operation

The database application I am working on can have a window with multiple NSTextView elements for displaying and editing data. When the current spot in the database is repositioned, all of the NSTextView objects in the window need to be updated with new contents. This is done with a loop that scans each object and checks to see if it needs to be updated. If it does, the new value is calculated, then updated by using the [NSTextView setString:] method. Here is a simplified version of the code involved.
for formObject in formObjectsInWindow {
NSTextView * objectTextView = [formObject textView];
NSString * updatedValue = [formObject calculateValue];
[objectTextView setString: updatedValue];
}
This works, but if there are a lot of objects, it is somewhat slow. Probably related, the display does not update all at once, you can actually see a "ripple" as the objects are updated, as illustrated in this movie (this movie has been slowed down to 1/4 speed to make the ripple effect more pronounced, but it is definitely visible at full speed).
If you've gotten this far, you might suspect that the calculateValue method is slow, but that isn't the problem. In other places the same code is used and runs at tens of thousands of operations per second. Also, this delay only occurs during update operations, it doesn't occur when the window is first opened, even though the same calculations are required at that time. Here is an example. Notice that when I switch back to the detail view all the NSTextView objects update instantaneously, even though the record changed and all of the values are different.
My suspicion is that the [NSTextView setString:] method is updating the off-screen buffer, then immediately copying that to the on-screen buffer, so that this double buffering is happening over and over again for each item, causing the delay and ripple. If so, I'm sure there must be some way to prevent this so that the screen is only updated at the end after all of the values have been updated. It's probably something simple that I am missing, but I'm afraid I am stumped as to how this is supposed to be done.
By the way, this application does not use layer-backed views, and is not linked against the QuartzCore framework.
I brought up this question with Apple engineers at the WWDC 2018 labs. It turns out the problem is that the setString: method does not mark the NSTextView object as needing display. The system does eventually notice that the text has changed and updates the display, but this happens in an asynchronous process, hence the "ripple" effect. So the workaround is simply to add a call to setNeedsDisplay after calling setString.
[objectTextView setString: updatedValue]
[objectTextView setNeedsDisplay:YES];
Adding this one line of code fixed the problem, no more ripple effect.
I'm told that this is actually a bug, so hopefully this extra line won't be needed in future versions of macOS. As requested, a radar has been filed (41273611 if any Apple engineers are reading this).

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.

MATLAB: Prevent figures from being made active

I have a rather large routine which will can run for a couple of hours. Here and there it creates a figure, plots something to it and saves that Figure.
As I have only one PC, I would like to continue to work with that machine. The problem is that whenever a new figure is made, MATLAB becomes the active application again.
Is there any way to tell MATLAB or Windows that MATLAB should not be allowed to set itself to active?
I saw that one possibility is to run a MATLAB script totally in the background (like that). But that is a little bit too unsupervised, as I would like to be able to switch to the MATLAB window and check the output to the command window.
Any ideas? If there is a general solution for Windows that prevents that other Applications to become active would also be cool!
You can overload the figure function as following in order to prevent figure poping up:
a = figure('visible','off');
I hate to state the obvious, but you could always store the data you want to plot until the end.
Now, you're going to tell me that some of that data is subroutines and doesn't get passed back to the main routine. OK. So, the solution to that would be to write a "Store_Plot_Data" class with a method that would write into memory the data, the #plot_function_name (for 3D, scatter, etc.), the axis label strings, etc. Then you would create one instance of this class in your main routine and to ensure visibility of this one instance to all subroutines you could do any of the following:
use a global variable as your single instance ... OK, not so elegant,
implement the Singleton pattern, or
pass all subroutines the handle to that one instance of the "Store_Plot_Data" class.
If there is a general solution for Windows that prevents that other
Applications to become active would also be cool!
In Windows 7, this worked for me:
http://pcsupport.about.com/od/windowsxp/ht/stealingfocus02.htm
Set "HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundLockTimeout" to 30d40 (hex).
If you want all figures to not show.
set(0,'defaultFigureVisible','off');
In the beginning of your script do:
set(0, 'DefaultFigureVisible', 'off');
set(0, 'DefaultFigureWindowStyle', 'docked');
Dock the Matlab figure window and maximize any other application (Excel, Word etc.) you are working with in front of Matlab.
Then you can continue to work without being interrupted by figures blinking on your face.

Tetris and pretty graphics

Say you're building a Tetris game. As any proper programmer, you have your view logic on one side, and your business logic on the other side; probably a full-on MVC going on.
When the model sends its update(), the view redraws itself, as expected.
But then... if you wanted to add, say, an animation to vanish a line, how would you implement that in the view?
Make any assumptions you want---excepting that "Everything is properly encapsulated".
Personally, I would separate draw the screen as often as possible, even if there was no update of the block position. So I would have a loop somewhere with an "update" and a "render" part. Update plays the ball to the logic which does or does not any update of positions and/or block removal. Render plays the ball to the graphics part, which draws the blocks where they should be.
Now if there are lines to erase, the logic knows and can mark those lines to be removed. I assume here, that every piece consists of 4 single blocks and any of these blocks is a single object. Now when this block has the "die"-flag set, you may take some render-parts to vanish the block (let's say, 500ms to explode). After this time, the object may be disposed and the block a line above falls down. Why 500ms? Well, you should definitely use time-based movement as this keeps the game speed the same on different computers.
Btw, there are already so called game engines which provide such an update-render-loop. For example XNA, if you go the .NET line. You may also code your own engine but beware, it's not an easy task and it's very time consuming. I did this once and don't expect it to be an engine like the Source Engine ;-)
Most games execute a loop that constantly redraws the view of the game as fast as possible, rather than waiting for a change in the model state and then refreshing the view.
If you like the model view pattern, then it might work well for the view to continue to draw some types of objects after they are removed from the model, fading them out over a few milliseconds.
Another approach would be to combine class MVC with something like differential execution - the 'view' is a model of what is presented, but the drawing code compares the stream of events the 'view' creates with the stream from the previous rendering. So if in one stream there's a line, and the next there isn't, the drawing code can animate the difference. This allows the drawing to be abstracted away from the view . Frequently the 'view' in MVC is a collection of widgets, rather than being something which draws the display directly, so you end up with nested MVC hierarchies anyway: the application is MVC ( data model, view objects, app controller ), where the view object has a collection of widgets each of which is MVC ( widget state (eg button pressed ), look and feel/toolkit binding, mapping of toolkit events -> widget state ).
I've often wondered this myself.
My own thoughts have been along this line:
1) The view is given the state of the blocks (shape, yada-yada), but with extra "transitional" data:
2) The fact that a line must be removed is encoded in the state, NOT computed in the view.
3) The view knows how to draw transitions now:
No change: state is the same for this particular block
Change from "falling" to "locked": state is "locked in" (by a dropping block)
Change from "locked" to "remove": state is "removed" (by a line completion)
Change from "falling" to "remove": state is "removed", but old state was "falling"
Its interesting to think of a game as an MVC. Thats a perspective I've never taken (for some odd reason), but definitely an intriguing one that makes a lot of sense. Assuming you do implement your Tetris game with an MVC, I think there are two things you might want to take into account in regards to communication between your controller and your view: There is state, and there are events.
Your controller is obviously the central point of interaction for the user. When they issue keyboard commands, your controller will interpret them, and make the appropriate state adjustments. However, sometimes the game will enter a state that coincides with a particular event...such as filling a line with blocks that should now be removed.
Scoregraphic has given you a great foundation. Your view should operate on a fixed cycle to maintain consistent speed across computers. But in addition to updating the screen to render new state, it should also have a queue of events that it can perform animations in response to. In the case of filling lines in Tetris, your controller could issue strongly typed event objects that derive from some kind of base event type into the view event queue, which could then be used by the view to perform the appropriate animated responses.

Resources