Coroutines/MYCoroutine.m
changeset 0 deb0ee0c5b21
child 1 2475f871c218
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Coroutines/MYCoroutine.m	Tue Apr 29 17:05:32 2008 -0700
     1.3 @@ -0,0 +1,173 @@
     1.4 +//
     1.5 +//  MYCoroutine.m
     1.6 +//  Coroutines
     1.7 +//
     1.8 +//  Created by Jens Alfke on 4/29/08.
     1.9 +//  Copyright 2008 Jens Alfke. All rights reserved.
    1.10 +//  License is at the bottom of this file.
    1.11 +//
    1.12 +
    1.13 +#import "MYCoroutine.h"
    1.14 +#import "CoroX.h"
    1.15 +
    1.16 +
    1.17 +#ifndef LogTo
    1.18 +#define kEnableLog 0    /* 1 enables logging, 0 disables it */
    1.19 +#define LogTo(DOMAIN,MSG,...) do{ if(kEnableLog) NSLog(@""#DOMAIN ": " MSG,__VA_ARGS__); }while(0)
    1.20 +#endif
    1.21 +
    1.22 +#ifndef Warn
    1.23 +#define Warn(MSG,...) NSLog(@"WARNING: " #MSG,__VA_ARGS__)
    1.24 +#endif
    1.25 +
    1.26 +
    1.27 +@implementation MYCoroutine
    1.28 +
    1.29 +
    1.30 +static MYCoroutine *sMain, *sCurrent;
    1.31 +
    1.32 +
    1.33 ++ (void) initialize
    1.34 +{
    1.35 +    if( self == [MYCoroutine class] ) {
    1.36 +        sMain = [[self alloc] init];
    1.37 +        Coro_initializeMainCoro(sMain->_coro);
    1.38 +        sMain.name = @"MAIN";
    1.39 +        sCurrent = sMain;
    1.40 +    }
    1.41 +}
    1.42 +
    1.43 +
    1.44 +- (id) init
    1.45 +{
    1.46 +    self = [super init];
    1.47 +    if (self != nil) {
    1.48 +        _coro = Coro_new();
    1.49 +        LogTo(Coroutine,@"INIT %@ : _coro=%p",self,_coro);
    1.50 +    }
    1.51 +    return self;
    1.52 +}
    1.53 +
    1.54 +
    1.55 +- (void) dealloc
    1.56 +{
    1.57 +    LogTo(Coroutine,@"DEALLOC %@",self);
    1.58 +    Coro_free(_coro);
    1.59 +    [super dealloc];
    1.60 +}
    1.61 +
    1.62 +
    1.63 +- (NSString*) description
    1.64 +{
    1.65 +    if( _name )
    1.66 +        return [NSString stringWithFormat: @"%@[%@]", [self class],_name];
    1.67 +    else
    1.68 +        return [NSString stringWithFormat: @"%@[%p]", [self class],self];
    1.69 +}
    1.70 +
    1.71 +
    1.72 +@synthesize name=_name;
    1.73 +
    1.74 +
    1.75 ++ (MYCoroutine*) mainCoroutine          {return sMain;}
    1.76 ++ (MYCoroutine*) currentCoroutine       {return sCurrent;}
    1.77 +
    1.78 +- (BOOL) isCurrent                      {return self==sCurrent;}
    1.79 +
    1.80 +- (const void*) stack                   {return Coro_stack(_coro);}
    1.81 +- (size_t) stackSize                    {return Coro_stackSize(_coro);}
    1.82 +- (void) setStackSize: (size_t)size     {Coro_setStackSize_(_coro,size);}
    1.83 +
    1.84 +- (size_t) bytesLeftOnStack             {return Coro_bytesLeftOnStack(_coro);}
    1.85 +- (BOOL) stackSpaceAlmostGone           {return Coro_stackSpaceAlmostGone(_coro);}
    1.86 +
    1.87 +
    1.88 +static void startWithInvocation( void *context )
    1.89 +{
    1.90 +    [(NSInvocation*)context invoke];
    1.91 +}
    1.92 +
    1.93 +static void startWithMain( void *context )
    1.94 +{
    1.95 +    [(MYCoroutine*)context main];
    1.96 +}
    1.97 +
    1.98 +- (void) startWithInvocation: (NSInvocation*)invocation
    1.99 +{
   1.100 +    LogTo(Coroutine,@"Starting %@ (currently in %@)",self,sCurrent);
   1.101 +    MYCoroutine *current = sCurrent;
   1.102 +    sCurrent = self;
   1.103 +    
   1.104 +    if( invocation )
   1.105 +        Coro_startCoro_(current->_coro, _coro, invocation, &startWithInvocation);
   1.106 +    else
   1.107 +        Coro_startCoro_(current->_coro, _coro, self, &startWithMain);
   1.108 +    
   1.109 +    sCurrent = current;
   1.110 +    LogTo(Coroutine,@"...resumed %@ after starting %@",sCurrent,self);
   1.111 +}
   1.112 +
   1.113 +- (void) start
   1.114 +{
   1.115 +    [self startWithInvocation: nil];
   1.116 +}
   1.117 +
   1.118 +
   1.119 ++ (MYCoroutine*) startWithInvocation: (NSInvocation*)invocation
   1.120 +{
   1.121 +    MYCoroutine *cr = [[self alloc] init];
   1.122 +    [cr startWithInvocation: invocation];
   1.123 +    return cr;
   1.124 +}
   1.125 +
   1.126 +
   1.127 +- (void) resume
   1.128 +{
   1.129 +    LogTo(Coroutine,@"Resuming %@ (currently in %@)",self,sCurrent);
   1.130 +    MYCoroutine *current = sCurrent;
   1.131 +    sCurrent = self;
   1.132 +    Coro_switchTo_(current->_coro,_coro);
   1.133 +    sCurrent = current;
   1.134 +    LogTo(Coroutine,@"...resumed %@",sCurrent);
   1.135 +}
   1.136 +
   1.137 +
   1.138 +- (void) main
   1.139 +{
   1.140 +    // subclasses should override this.
   1.141 +}
   1.142 +
   1.143 +
   1.144 +@end
   1.145 +
   1.146 +
   1.147 +
   1.148 +
   1.149 +/*
   1.150 + (This is a BSD License)
   1.151 + 
   1.152 + Copyright (c) 2008 Jens Alfke
   1.153 + All rights reserved.
   1.154 + 
   1.155 + Redistribution and use in source and binary forms, with or without modification, are
   1.156 + permitted provided that the following conditions are met:
   1.157 + 
   1.158 + • Redistributions of source code must retain the above copyright notice, this list of
   1.159 + conditions and the following disclaimer.
   1.160 + • Redistributions in binary form must reproduce the above copyright notice, this list
   1.161 + of conditions and the following disclaimer in the documentation and/or other materials
   1.162 + provided with the distribution.
   1.163 + • Neither the name of the author nor the names of other contributors may be used to
   1.164 + endorse or promote products derived from this software without specific prior written
   1.165 + permission.
   1.166 + 
   1.167 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
   1.168 + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   1.169 + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   1.170 + THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   1.171 + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   1.172 + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   1.173 + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
   1.174 + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   1.175 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   1.176 +*/