Coroutines/MYCoroutine.m
author Jens Alfke <jens@mooseyard.com>
Tue Apr 29 17:05:32 2008 -0700 (2008-04-29)
changeset 0 deb0ee0c5b21
child 1 2475f871c218
permissions -rw-r--r--
First checkin
     1 //
     2 //  MYCoroutine.m
     3 //  Coroutines
     4 //
     5 //  Created by Jens Alfke on 4/29/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //  License is at the bottom of this file.
     8 //
     9 
    10 #import "MYCoroutine.h"
    11 #import "CoroX.h"
    12 
    13 
    14 #ifndef LogTo
    15 #define kEnableLog 0    /* 1 enables logging, 0 disables it */
    16 #define LogTo(DOMAIN,MSG,...) do{ if(kEnableLog) NSLog(@""#DOMAIN ": " MSG,__VA_ARGS__); }while(0)
    17 #endif
    18 
    19 #ifndef Warn
    20 #define Warn(MSG,...) NSLog(@"WARNING: " #MSG,__VA_ARGS__)
    21 #endif
    22 
    23 
    24 @implementation MYCoroutine
    25 
    26 
    27 static MYCoroutine *sMain, *sCurrent;
    28 
    29 
    30 + (void) initialize
    31 {
    32     if( self == [MYCoroutine class] ) {
    33         sMain = [[self alloc] init];
    34         Coro_initializeMainCoro(sMain->_coro);
    35         sMain.name = @"MAIN";
    36         sCurrent = sMain;
    37     }
    38 }
    39 
    40 
    41 - (id) init
    42 {
    43     self = [super init];
    44     if (self != nil) {
    45         _coro = Coro_new();
    46         LogTo(Coroutine,@"INIT %@ : _coro=%p",self,_coro);
    47     }
    48     return self;
    49 }
    50 
    51 
    52 - (void) dealloc
    53 {
    54     LogTo(Coroutine,@"DEALLOC %@",self);
    55     Coro_free(_coro);
    56     [super dealloc];
    57 }
    58 
    59 
    60 - (NSString*) description
    61 {
    62     if( _name )
    63         return [NSString stringWithFormat: @"%@[%@]", [self class],_name];
    64     else
    65         return [NSString stringWithFormat: @"%@[%p]", [self class],self];
    66 }
    67 
    68 
    69 @synthesize name=_name;
    70 
    71 
    72 + (MYCoroutine*) mainCoroutine          {return sMain;}
    73 + (MYCoroutine*) currentCoroutine       {return sCurrent;}
    74 
    75 - (BOOL) isCurrent                      {return self==sCurrent;}
    76 
    77 - (const void*) stack                   {return Coro_stack(_coro);}
    78 - (size_t) stackSize                    {return Coro_stackSize(_coro);}
    79 - (void) setStackSize: (size_t)size     {Coro_setStackSize_(_coro,size);}
    80 
    81 - (size_t) bytesLeftOnStack             {return Coro_bytesLeftOnStack(_coro);}
    82 - (BOOL) stackSpaceAlmostGone           {return Coro_stackSpaceAlmostGone(_coro);}
    83 
    84 
    85 static void startWithInvocation( void *context )
    86 {
    87     [(NSInvocation*)context invoke];
    88 }
    89 
    90 static void startWithMain( void *context )
    91 {
    92     [(MYCoroutine*)context main];
    93 }
    94 
    95 - (void) startWithInvocation: (NSInvocation*)invocation
    96 {
    97     LogTo(Coroutine,@"Starting %@ (currently in %@)",self,sCurrent);
    98     MYCoroutine *current = sCurrent;
    99     sCurrent = self;
   100     
   101     if( invocation )
   102         Coro_startCoro_(current->_coro, _coro, invocation, &startWithInvocation);
   103     else
   104         Coro_startCoro_(current->_coro, _coro, self, &startWithMain);
   105     
   106     sCurrent = current;
   107     LogTo(Coroutine,@"...resumed %@ after starting %@",sCurrent,self);
   108 }
   109 
   110 - (void) start
   111 {
   112     [self startWithInvocation: nil];
   113 }
   114 
   115 
   116 + (MYCoroutine*) startWithInvocation: (NSInvocation*)invocation
   117 {
   118     MYCoroutine *cr = [[self alloc] init];
   119     [cr startWithInvocation: invocation];
   120     return cr;
   121 }
   122 
   123 
   124 - (void) resume
   125 {
   126     LogTo(Coroutine,@"Resuming %@ (currently in %@)",self,sCurrent);
   127     MYCoroutine *current = sCurrent;
   128     sCurrent = self;
   129     Coro_switchTo_(current->_coro,_coro);
   130     sCurrent = current;
   131     LogTo(Coroutine,@"...resumed %@",sCurrent);
   132 }
   133 
   134 
   135 - (void) main
   136 {
   137     // subclasses should override this.
   138 }
   139 
   140 
   141 @end
   142 
   143 
   144 
   145 
   146 /*
   147  (This is a BSD License)
   148  
   149  Copyright (c) 2008 Jens Alfke
   150  All rights reserved.
   151  
   152  Redistribution and use in source and binary forms, with or without modification, are
   153  permitted provided that the following conditions are met:
   154  
   155  • Redistributions of source code must retain the above copyright notice, this list of
   156  conditions and the following disclaimer.
   157  • Redistributions in binary form must reproduce the above copyright notice, this list
   158  of conditions and the following disclaimer in the documentation and/or other materials
   159  provided with the distribution.
   160  • Neither the name of the author nor the names of other contributors may be used to
   161  endorse or promote products derived from this software without specific prior written
   162  permission.
   163  
   164  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
   165  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   166  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   167  THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   168  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   169  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   170  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
   171  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   172  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   173 */