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