Re: NSView confusion
Re: NSView confusion
- Subject: Re: NSView confusion
- From: Graham Cox <email@hidden>
- Date: Thu, 21 Aug 2008 14:05:47 +1000
On 21 Aug 2008, at 1:19 am, Charlie Dickman wrote:
Sounds like a declaration issue :-)
That may be what it sounds like but I've tried every which way I can
to declare it differently to no avail.
Except, presumably, the correct way, otherwise your problem would have
been solved.
So:
//MyView.h
@interface MyView : NSView
- (void) myViewMethod;
@end
//MyView.m
#import "MyView.h"
@implementation MyView
- (void) myViewMethod
{
NSLog(@"my view method called");
}
@end
// MyOtherView.h
@class MyView;
@interface MyOtherView : NSView
{
IBOutlet MyView* firstView;
}
- (void) callTheOtherView;
@end
//MyOtherView.m
#import "MyOtherView.h"
#import "MyView.h"
@implementation MyOtherView
- (void) callTheOtherView
{
// assumes the outlet 'firstView' has been set up in IB or
otherwise set up
[firstView myViewMethod];
}
@end
The above should compile without warnings or errors (caveat: typed
into Mail). Whether it's useful is another question. Comparison with
your code will hopefully indicate where your problem is.
"view" is an NSView and method is not spelled wrong. As I said, I
can call it just fine with [view performSelector at run-time.
If it's an NSView, and not the specific type of custom view, then
'method' isn't a method of NSView, it's a method of 'MyView' (or
whatever). So of course it's not going to compile without a warning.
Also, how does one synchronize events with the update of the
various views? I can instruct each view what to draw and it draws
it just fine (I use lockFocus, etc. when drawing is external to
drawRect) and the updated view is seen _eventually_ but I can not
synchronize subsequent activity to happen after the appropriate
display is seen. How can I accomplish this synchronization? And
how can I force a view to update? Invoking [view display] has no
effect on forcing the display toshow the latest update.
Calling [view setNeedsDisplay:YES] is the most common way of
updating. Unless you're writing a 2d game, you'll want to use this
95% of the time.
Make that 99.99% of the time.
Can you point out in what way my previous reply wasn't helpful?
I call lock focus whenever I'm drawing outside the purview of
drawRect. This is the way the documentation says to do it.
Which documentation is that? I think you'll find that the same
documentation also goes to pains to point out that this is only done
in unusual, exceptional circumstances, and isn't the normal MO for
updating a view.
And I am writing a 2d game and things that need to be clicked on are
constantly being updated but the display does not match the internal
game conditions so the appropriate objects can not be selected.
The "internal game conditions" are otherwise known as your data model.
The view has no business managing this, especially if there is more
than one view of the same data. Put that into a separate object. The
data model can be linked to the view(s) that display its state through
another object called a controller. Typically there would be one
controller per view, or you could design your controller so that it
manages several views. The controller "knows about" the views. The
data model "knows about" the controllers. When the data model state
changes, it flags the need for an update to its controllers. In turn
these call -setNeedsDisplayInRect: on the view it manages. The view
then receives a later call to -drawRect: It then arranges to repaint
itself by grabbing the data from the model via its controller, or
asking the controller to redraw the model, or asking the individual
objects in the model to redraw themselves (various ways to handle this).
I can't see how the view's image of the game can get out of synch with
the real game state when you do it this way (which is entirely
conventional). Trying to force the screen to "keep up" with state
changes is normally pointless. Instead, let the screen update rate
force a "clock" onto your game so that everything is locked to the
event loop. Normally this just happens this way because timers that
might be driving your game are driven by the event loop, view updates
are locked to the event loop, and mouse/user input events are locked
to the event loop. Screen updates are maxed out to 60fps so you can't
refresh faster than this, but that gives you a huge amount of time to
calculate/update your game state. How is your game state driven?
Unless it's running under another thread I can't see how its state can
"run away" from the state shown in the views.
Selecting an item is simply a change of state in your data model.
There's no reason this needs to be handled in any special way other
than the above. It should not be possible for an object to be in a
position other than where it appears to be in the view since a change
of position is a change of state and that should update the view as
usual.
Also, don't assume you need to optimise this at this stage. A 2D game
should be well within standard Cocoa's available performance, so get
it working with everything handled conventionally. If it's
subsequently necessary to optimise to get smoother movement, etc,
worry about that then.
A tip: games that involve moving objects should never base their
position calculations on a fixed framerate. Instead, if an object has
a velocity V then its new position P' depends on the time elapsed t
since the last time it was updated and its previous position P; P'= P
+ Vt. Thus your objects are always in the right place no matter how
fast or slow the updates happen to be occurring. Naive code often
assumes the value of t is constant and equal to some theoretical
framerate and so things get out of position when updates can't be
processed fast enough. The effect for the player is that things move
faster or slower according to the achievable framerate. Instead, what
should happen is that things are always in the right place but the
framerate can go faster or slower according to what is achievable.
This is far less noticeable. Not sure if this has a bearing on your
problem but if you are assuming a fixed value for t it would be a good
idea to revise that code sooner rather than later.
hth,
cheers, Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden