Hi,

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

Reply via email to