This is MOController.m in view mode; [Download] [Up]
// MOController.m
//
// by Mike Ferris
// Part of MOKit
// Copyright 1993, all rights reserved.
// ABOUT MOKit
//
// MOKit is a collection of useful and general objects. Permission is
// granted by the author to use MOKit in your own programs in any way
// you see fit. All other rights to the kit are reserved by the author
// including the right to sell these objects as part of a LIBRARY or as
// SOURCE CODE. In plain English, I wish to retain rights to these
// objects as objects, but allow the use of the objects as pieces in a
// fully functional program. NO WARRANTY is expressed or implied. The author
// will under no circumstances be held responsible for ANY consequences to
// you from the use of these objects. Since you don't have to pay for
// them, and full source is provided, I think this is perfectly fair.
#import "MOKit/MOController.h"
#import "MOKit/MOString.h"
#import "MOKit/MOClassVariable.h"
#import <objc/objc-runtime.h>
#define CLASS_VERSION 0
#define CLASS_NAME "MOController"
#define BUNDLE_TYPE "bundle"
#define MOSTRING_CLASS_NAME "MOString"
#define MOCLASSVARIABLE_CLASS_NAME "MOClassVariable"
@interface MOController(Private)
+ (Class)MO_loadClassBundle:(const char *)className;
@end
@implementation MOController
// True class variable object
static MOClassVariable *MO_classNib;
// Looked up classes we use
static Class MOStringClass;
static Class MOClassVariableClass;
+ (Class)MO_loadClassBundle:(const char *)className
// Finds the bundle of the same name as the class, grabs it and loads the
// class from it and returns the named class.
{
char pathBuff[MAXPATHLEN+1];
id classBundle = nil;
Class class = nil;
// Load the bundle
if ((class = objc_lookUpClass(className)) == nil) {
// class is not already loaded... load it.
// Look for the bundle in the main bundle first,
// else try in this class's bundle.
if (![[NXBundle mainBundle] getPath:pathBuff forResource:className
ofType:BUNDLE_TYPE]) {
if (![[NXBundle bundleForClass:[self class]] getPath:pathBuff
forResource:className ofType:BUNDLE_TYPE]) {
NXLogError("[%s loadClassBundle] failed to "
"find %s class bundle.", [self name], className);
return nil;
}
}
classBundle = [[NXBundle allocFromZone:[self zone]]
initForDirectory:pathBuff];
if (!classBundle) {
NXLogError("[%s loadClassBundle] failed to "
"create bundle for class %s.", [self name], className);
return nil;
}
if ((class = [classBundle classNamed:className]) == nil) {
NXLogError("[%s loadClassBundle] failed to "
"load %s class from bundle.", [self name], className);
return nil;
}
}
return class;
}
+ initialize
// Set the version. Load classes, and init class variables.
{
if (self == objc_lookUpClass(CLASS_NAME)) {
[self setVersion:CLASS_VERSION];
// Load the string class if necessary
MOStringClass = [self MO_loadClassBundle:MOSTRING_CLASS_NAME];
MOClassVariableClass = [self MO_loadClassBundle:
MOCLASSVARIABLE_CLASS_NAME];
// Set up class variables
MO_classNib = [[MOClassVariableClass allocFromZone:[self zone]]
initDoesFreeValues:YES];
}
return self;
}
+ setClassNib:(const char *)nibName
// Set the nib file which contains the window this controller class controls.
{
id newVal;
if (nibName) {
newVal = [[MOStringClass allocFromZone:[self zone]]
initStringValue:nibName];
} else {
newVal = nil;
}
[MO_classNib setObject:newVal forClass:self];
return self;
}
+ (const char *)classNib
// Returns the nib file name for this controller class.
{
return [(MOString *)[MO_classNib getObjectForClass:self] stringValue];
}
+ startUnloading
// Free our class variables.
{
[MO_classNib free];
return self;
}
- init
// Just calls the DI.
{
return [self initWithFrameName:NULL];
}
- initWithFrameName:(const char *)theFrameName
// Designated Initializer.
// Initialize some instance variables.
{
[super init];
nibIsLoaded=NO;
window=nil;
frameName = [[MOStringClass allocFromZone:[self zone]]
initStringValue:theFrameName];
return self;
}
- free
// Free our window, and frameName.
{
if (window) [window free];
[frameName free];
return [super free];
}
- setFrameName:(const char *)theFrameName
// Sets the name to save the windows frame info under in the defaults
// database.
{
[frameName setStringValue:theFrameName];
return self;
}
- (const char *)frameName
// Return the name to save the windows frame info under in the defaults
// database.
{
return [frameName stringValue];
}
- nibDidLoad
// This is called after our nib has been loaded. You may override it to do
// whatever needs to be done. But call super's implementation first.
{
return self;
}
- loadNibIfNeeded
// Loads the nib file if it hasn't already been loaded. Also performs
// set up that must be deferred till the nib is loaded.
{
const char *nibName = [[self class] classNib];
const char *frmName = NULL;
if ((!nibIsLoaded) && (nibName) && (*nibName)) {
if (![NXApp loadNibSection:nibName owner:self]) {
NXLogError("[%s loadNibIfNeeded]: failed to load nib file %s.",
[[self class] name], nibName);
return nil;
}
nibIsLoaded = YES;
// configure window
frmName = [self frameName];
if ((frmName) && (*frmName)) {
[window setFrameAutosaveName:frmName];
[window setFrameUsingName:frmName];
}
[self nibDidLoad];
}
return self;
}
- window
// Return the window. (Returns nil if the nib file is not loaded.)
{
return [self window:NO];
}
- window:(BOOL)loadFlag
// Return the window. (If loadFlag is NO and window is not loaded,
// returns nil. If loadFlag is YES, window is loaded if necessary.)
{
if (loadFlag) [self loadNibIfNeeded];
return window;
}
- showWindow:sender
// Show the window (loading it first if necessary).
{
[self loadNibIfNeeded];
if (window) [window makeKeyAndOrderFront:sender];
return self;
}
- awake
// Sets up ivars we don't archive.
{
window = nil;
nibIsLoaded = NO;
return self;
}
- read:(NXTypedStream *)strm
// This method is probably not useful, but here it is for completeness sake.
{
int classVersion;
[super read:strm];
classVersion = NXTypedStreamClassVersion(strm, CLASS_NAME);
switch (classVersion) {
case 0: // First version.
frameName = NXReadObject(strm);
break;
default:
NXLogError("[%s read:] class version %d cannot read "
"instances archived with version %d",
CLASS_NAME, CLASS_VERSION, classVersion);
frameName = [[MOStringClass allocFromZone:[self zone]] init];
break;
}
return self;
}
- write:(NXTypedStream *)strm
// This method is probably not useful, but here it is for completeness sake.
{
[super write:strm];
NXWriteObject(strm, frameName);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.