NSOGL Document Based

Feanor
Unregistered
 
Post: #16
The names of your classes are easily accessible using the otool command from the Terminal, so I would not worry about that.
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #17
> The names of your classes are easily accessible using the otool command from the Terminal, so I would not worry about that.

Oh well so much for security on Unix right?

Ok I got the window switching bug fixed. Also I never knew about those "# pragma mark" things until I saw Feanors Cavern code. The pragma mark that you put next to windowWillClose was a give away arek. Thanks. Here's how I got it working:
Code:
// MyDocument.m
// arek's code
#pragma mark _____ Window delegates _____

- (void)windowWillClose:(NSNotification *)aNotification
{
    [theOGLView stopTimer];
}
// arek's code

- (void)windowDidResignMain:(NSNotification *)notification
{
    [theOGLView stopTimer];
}

- (void)windowDidBecomeMain:(NSNotification *)notification
{
    [theOGLView startTimer];
}

// TheOGLView.m
NSTimer *timer;

- (void)dealloc
{    
    [timer invalidate];
    [timer release];
// Why does timer have to be released here?

// releasing other objects here

    [super dealloc];
}

- (void)startTimer
{
// Timer retainCount = 1 or 0
    if (timer != nil)
        [timer release];

    timer = [[NSTimer scheduledTimerWithTimeInterval: 0.0
        target:self
        selector:@selector(drawFrame)
        userInfo:nil
        repeats:YES]
        retain];
                
    [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSEventTrackingRunLoopMode];
    [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSModalPanelRunLoopMode];

// Timer retainCount = 5
}

// arek's code
- (void)stopTimer
{
// Why does timer = 4 and not 5?
// Timer retainCount = 4
    [timer invalidate];
// Timer retainCount = 1
// Why does it crash when I call [timer release]; here?
// I tried the debugger but it just gives me the spinning beach ball.
}
// arek's code

There I think I got everything. How did I do?

Thanks,
Iceman
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #18
Hm, so with your window resigning, you will have only one document animating at a time. That's fine, I didn't know what your intention was...

A few points:

You have to release the timer in dealloc, because you retained it in the GLview init. You also have to invalidate it there, because there is no guarantee that you've invalidated it elsewhere. Theoretically, you could be nuking and recreating the GLview while there is only one window (say your interface grows to have multiple panes or something...)

Now, in startTimer, you are testing against nil. If you do this, you better be sure that you have explicitly set timer to nil after you release it-- just releasing an object does not set the pointer to zero automatically. That may be the cause of your retainCount wierdness.

And, don't use 0.0 for scheduledTimerWithTimeInterval. Use the largest value that works for you, say, 0.01 or 0.005 for 100 or 200Hz.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #19
Quote:Originally posted by Iceman
Oh well so much for security on Unix right?

Security through obfuscation is no security. Smile

Basically, any scheme that depends on the user not knowing the internal structure is doomed to failure. Any hacker worth their salt will just step through the code one assembly instruction at a time. You should assume hackers HAVE YOUR SOURCE.

Real security involves encryption, big numbers, and hoping quantum computing stays away. Smile
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #20
Quote:Originally posted by arekkusu
Hm, so with your window resigning, you will have only one document animating at a time.
Hey you can't press keys in both windows at once Rasp. This also helps improve performance since I have 8MB of vram.

Quote:Originally posted by arekkusu
Now, in startTimer, you are testing against nil. If you do this, you better be sure that you have explicitly set timer to nil after you release it-- just releasing an object does not set the pointer to zero automatically. That may be the cause of your retainCount wierdness.[/b]
Hmm tried and it didn't do anything. What number should "timer" equal at the end of startTimer?

Quote:Originally posted by arekkusu
And, don't use 0.0 for scheduledTimerWithTimeInterval. Use the largest value that works for you, say, 0.01 or 0.005 for 100 or 200Hz. [/b]
0.0 sets it to the smallest number which is something like 0.005 so what would be the problem?

Iceman
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #21
"timer" will equal whatever the address of the allocated NSTimer is. Something that is not nil. After you deallocate it, is still isn't nil, so your check to see if the object exists will always succeed, unless you explicitly set the pointer to nil.


0.0 isn't "something like" 0.005, it is "as fast as possible" which just wastes CPU and makes your users angry. You can prove this to yourself really easily:

1) comment out all the code in your timer's target method (drawFrame) so that you are only measuring the timer overhead.
2) run your app with a sensible timer interval of 0.01. On my machine, your app now uses ~0.0% of the CPU.
3) run your app with a timer interval of 0.0. On my machine, your app now uses ~26% of the CPU. The timer is firing as soon as the runloop allows it, which is millions of time every second.

The only time an interval of 0.0 is acceptable is when you use a NON repeating timer and want its target to run immediately after the current method exits and control passes back to the runloop. There are some uses for this...
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #22
Ok I set the timer back to 0.005. I also got the highlighter bug fixed. I'm using timer = nil in startTimer too.

Thanks,
Iceman
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #23
I finally figured out Feanor's code (very nice I must say) since my app wasn't decoding properly. So my question is how do I get the - (void)keyDown:(NSEvent *)theEvent method to work in Cavern Quest? And where do I put it since CQDocument can't accept responders?

Thanks,
Iceman
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #24
Hmm I can't get Feanor's CQ code to decode anything either. All I get is a sigbus or a black window. Help me please.

Iceman
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #25
For the responder, no the document cannot catch events since it is subclassed directly from NSObject. Remember, its role is to manage data, not perform user interaction.

You need an NSResponder subclass. A window or a view qualifies. Try putting keyDown in your view, or subclassing NSWindow.


For decoding, it depends entirely on how your data model is implemented. If you are getting a seg fault, use the debugger to check your object pointers. Then trace backwards to find where you've gone wrong.
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #26
Thank you for the pointers. I tried everything you said and I got it working. Amazing! I guess it helps when you start on another project and then come back to the one you're having trouble on. Now I just need to rewrite my map editor code so it will work. Grrrr I hate it when I don't stick to the Cocoa way of programming. Modularity, Modularity, Modularity.

Thanks again,
Iceman
Quote this message in a reply
Feanor
Unregistered
 
Post: #27
Glad you figured it out. Sorry I was not around the last few days to answer your questions. I think I need a break from programming, but it doesn't look like I am going to get one.

Feel free to use the e-mail feature in the forum if I seem not to be posting. I nearly always answer e-mail.
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #28
Ok I'll do that next time. The thing I forgot to mention was that the NSOGLView was linked to all my files that decoded stuff. So everytime I tried opening a file all the decoded stuff would be reset to the Class's -(id)init. Not the newly loaded file. Why? For some reason the NSViews are called after MyDocuments.

Thanks,
Iceman
Quote this message in a reply
Feanor
Unregistered
 
Post: #29
Not completely sure I understand you, but I'll interpret that you were expecting to open a document and have certain view instance variables come back -- however, you would have to explicitly save the view in your file, which would cause a conflict with the nib and would violate MVC.

Every time you create a new instance object, either programmatically or by loading from nib, -init gets called, or -initWithCoder (which typically calls some other -init method first, to set all the non-object members).

The first thing I guess you should consider is that a view should not contain any persistent data -- that will probably make your problem go away. Otherwise, you will have to add code to the document to request the persistent data, store it in a dictionary, and archive it when saving, and then do the reverse when loading a document. View objects are not saved in document files, typically, nor should they be, thus none of their instance member data would be archived either, except outlets from the nib.

Does this make sense?
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #30
Yes that does make tons of sense now. At the time it was very frustrating and confusing Wacko .

Thanks,
Iceman
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Cocoa Document OpenGL App Question CarbonX 2 3,452 Dec 6, 2004 12:37 PM
Last Post: CarbonX