While speaking about gpbs crashing and long delay when restarting, i am sending a piece of code that should improve that. The code does quite fast launch&connect.
Attached are two files: one for server side (afsimulator.m) and the other for client side (remote.m). It works like this: Client launghes server and gives it some unique string as an argument. Client registers itself as distributed notification observer for a notification with object being that identifier. When server is ready it posts distributed notification with that unique identifier, so client knows when the server is ready. Client receives notification and can do immediate connect by NSConnection.
This is done asynchronously, however, some NSLock lockBeforeDate: mechansim can be used if you want to launch&connect and immediately use, as in app using gpbs.
Well, as usual, i have no time to play with it, so i am sending unmodified parts from one of my projects where i am using such code. I think it is not difficult to understand the code and modify it to suit particular needs (gpbs?). If someone finds this code useful, feel free to reuse it. Or just let me know what do you think of it (if it is ok, or not).
Best regards,
Stefan Urbanek -- http://urbanek.host.sk
First they ignore you, then they laugh at you, then they fight you, then you win. - Mahatma Gandhi
<afsimulator.m><remote.m>
/* 2003 Jun 14 */
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSException.h>
#import <Foundation/NSConnection.h>
#import <Foundation/NSUserDefaults.h>
#import <FarmsSimulator/AFSimulator.h>
#import <Foundation/NSDistributedNotificationCenter.h>
const int MAX_SEQUENCES = 100; /* Maximal number of simulator sequence numbers */
@class NSAutoreleasePool;
@class AFModelBundle;
int main(int argc, const char **argv)
{
NSDistributedNotificationCenter *dnc;
NSAutoreleasePool *pool;
NSUserDefaults *defs;
AFSimulator *simulator;
NSDictionary *dict;
NSConnection *connection;
NSString *userIdentifier;
NSString *serverName;
BOOL isRegistered = NO;
int sequence = 0;
pool = [NSAutoreleasePool new];
/* FIXME: make is missing framework linking */
[AFModelBundle class];
/* Get command line arguments */
defs = [NSUserDefaults standardUserDefaults];
userIdentifier = [defs objectForKey:@"AFUserIdentifier"];
serverName = [defs objectForKey:@"AFServerName"];
if([serverName isEqualtToString:@""])
{
serverName = nil;
}
/* Create simulator */
simulator = [[AFSimulator alloc] init];
/* Register simulator */
connection = RETAIN([NSConnection defaultConnection]);
[connection setRootObject:simulator];
if(!serverName)
{
for(sequence = 0; sequence < MAX_SEQUENCES; sequence++)
{
serverName = [NSString stringWithFormat:@"AFSimulator%i", sequence];
NSLog(@"Trying to register simulator with name '%@'", serverName);
NS_DURING
if([connection registerName:serverName])
{
isRegistered = YES;
break;
}
NS_HANDLER
NSLog(@"WARNING: GNUstep is broken! Report this to [EMAIL PROTECTED]");
NS_ENDHANDLER
}
}
else
{
if([connection registerName:serverName])
{
isRegistered = YES;
}
}
/* Finish */
if(isRegistered)
{
NSLog(@"Registered with name '%@'", serverName);
dnc = [NSDistributedNotificationCenter defaultCenter];
dict = [NSDictionary dictionaryWithObjectsAndKeys:
serverName, @"AFDistantSimulatorName",
nil, nil];
[dnc postNotificationName:@"AFDistantSimulatorConnectNotification"
object:userIdentifier
userInfo:dict];
[[NSRunLoop currentRunLoop] run];
NSLog(@"Terminating simulator server %@", serverName);
}
else
{
NSLog(@"Unable to register simulator.");
}
RELEASE(pool);
return 0;
}
@implementation SomethingConnectingToRemoteObject
- (oneway void)connectNew
{
NSArray *args;
if(simulator)
{
[NSException raise:@"AFDistantSimulatorException"
format:@"Simulator is already connected"];
return;
}
if(serverTask)
{
/* Just in case, terminate the server task */
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:NSTaskDidTerminateNotification
object:serverTask];
[serverTask terminate];
RELEASE(serverTask);
serverTask = nil;
}
ASSIGN(checkTime,[NSDate date]);
args = [NSArray arrayWithObjects:
@"-AFUserIdentifier",
identifier,
nil];
serverTask = [[NSTask alloc] init];
[serverTask setLaunchPath:@"afsimulator"];
[serverTask setArguments:args];
[[NSDistributedNotificationCenter defaultCenter]
addObserver:self
selector:@selector(_connectSimulator:)
name:@"AFDistantSimulatorConnectNotification"
object:identifier];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(_taskTerminated:)
name:NSTaskDidTerminateNotification
object:serverTask];
[serverTask launch];
NSLog(@"%@", serverTask);
}
- (void)_connectSimulator:(NSNotification *)notif
{
NSDictionary *dict = [notif userInfo];
NSString *serverName;
serverName = [dict objectForKey:@"AFDistantSimulatorName"];
/* We have received desired notification, therefore we should
unregister ourselves */
[[NSDistributedNotificationCenter defaultCenter]
removeObserver:self];
NSLog(@"Connection requested to %@", serverName);
[self _connectToServerWithName:serverName];
}
- (void)_connectToServerWithName:(NSString *)serverName
{
simulator = (NSDistantObject <AFSimulator> *)[NSConnection
rootProxyForConnectionWithRegisteredName:serverName
host:nil];
if(!simulator)
{
[NSException raise:@"AFDistantSimulatorException"
format:@"Unable to get distant simulator object from server
'%@'", serverName];
return;
}
RETAIN(simulator);
[(NSDistantObject *)simulator setProtocolForProxy:@protocol(AFSimulator)];
NSLog(@"Found simulator. Class: [EMAIL PROTECTED]", [(NSObject *)simulator
className]);
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(_connectionDidDie:)
name:NSConnectionDidDieNotification
object:[simulator connectionForProxy]];
NSLog(@"Connection time: %f", -[checkTime timeIntervalSinceNow]);
[[NSNotificationCenter defaultCenter]
postNotificationName:AFDistantSimulatorConnectedNotification
object:self];
}
@end
_______________________________________________ Bug-gnustep mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-gnustep
