// // ZoomConnector.m // ZoomCocoa // // Created by Andrew Hunter on 30/08/2004. // Copyright 2004 Andrew Hunter. All rights reserved. // #include #import "ZoomConnector.h" @implementation ZoomConnector // = The shared connector = + (ZoomConnector*) sharedConnector { static ZoomConnector* sharedConnector = nil; if (sharedConnector == nil) { sharedConnector = [[[self class] alloc] init]; } return sharedConnector; } // = Initialisation = - (id) init { self = [super init]; if (self) { // Create the connection that we'll use to allow ZoomServer processes to connect to us // (Originally, this was created by the ZoomServer processes themselves, but there is a limit to the // number of Mach ports that can be created in OS X. Exceeding the limit creates a kernel panic - an // OS X bug, but one we really don't want to provoke if possible) // // Unlikely that anyone ever encountered this: you need ~200-odd running games before things go // kaboom. NSString* connectionName = [NSString stringWithFormat: @"Zoom-%i", getpid()]; NSPort* port = [NSMachPort port]; connection = [[NSConnection connectionWithReceivePort: port sendPort: port] retain]; [connection setRootObject: self]; [connection addRunLoop: [NSRunLoop currentRunLoop]]; if (![connection registerName: connectionName]) { NSLog(@"Uh-oh: failed to register a connection. Games will probably fail to start"); } waitingViews = [[NSMutableArray alloc] init]; } return self; } - (void) dealloc { [waitingViews release]; [connection registerName: nil]; [connection release]; [super dealloc]; } // = Connecting views to Z-Machines = - (void) addViewWaitingForServer: (ZoomView*) view { [self removeView: view]; [waitingViews addObject: view]; } - (void) removeView: (ZoomView*) view { [waitingViews removeObjectIdenticalTo: view]; } - (id) connectToDisplay: (id) zMachine { // Get the view that's waiting ZoomView* whichView = [[[waitingViews lastObject] retain] autorelease]; if (whichView == nil) { NSLog(@"WARNING: attempt to connect to a display when no objects are available to connect to"); return nil; } // Remove from the list of waiting views [waitingViews removeLastObject]; // Notify the view that it's gained a Z-Machine [[NSRunLoop currentRunLoop] performSelector: @selector(setZMachine:) target: whichView argument: zMachine order: 16 modes: [NSArray arrayWithObject: NSDefaultRunLoopMode]]; // Using the runloop there stops the server from receiving any messages before this call returns. // As things currently stand, that basically ensures that this call returns at all before the Z-Machine // is terminated. This is non-critical as things stand, though. // We're done return whichView; } @end