A.3. GridTurtleコード例

Example A-1. GridTurtle.h

#import "grid.h"
#import <defobj/Create.h>

@interface GridTurtle_c : CreateDrop_s
{
@public
  int          x_coord;
  int          y_coord;
  direction_t  direction;
  member_t     listMembership;
}
@end

Example A-2. GridTurtle.m

#import "GridTurtle.h"

#define __USE_FIXED_PROTOTYPES__  // for gcc headers
#include <stdio.h>


@implementation GridTurtle_c

- (void) move: (int) distance
{
  switch (direction) {
  case north: y_coord += distance; break;
  case east:  x_coord += distance; break;
  case south: y_coord -= distance; break;
  case west:  x_coord -= distance; break;
  }
}

- (void) turn: (int) angle
{
  direction = ( direction - angle ) % 4;
}

- (void) print
{
  printf( "x coord: %d  y coord: %d  direction: %d\n",
           x_coord, y_coord, direction );
}

@end

Example A-3. Makefile

ifeq ($(SWARMHOME),)
SWARMHOME=../../../swarm
endif
include $(SWARMHOME)/etc/swarm/Makefile.common

OTHERINCDIRS=-I.
INCLUDES+=$(OTHERINCDIRS)

LIBS_C=		-lcollections -ldefobj -lmisc $(SYSLIBS)
LIBS_A=		-lactivity $(LIBS_C)

TARGETS_C= strtest grid0 grid1a grid1b grid1c grid2 grid2b grid3 grid3b \
           grid4 grid4b
TARGETS_A= grid5 grid6 grid7 grid8 grid9
TARGETS_M= mousetraps mousetraps2

OBJECTS= grid.o GridTurtle.o

all: $(TARGETS_C) $(TARGETS_A) $(TARGETS_M)

grid.o: grid/classes.h grid.xm

grid.xm: grid.h
	OBJC="$(OBJC)" OBJCFLAGS="$(OTHERINCDIRS) -I$(includedir) $(CPPFLAGS) \
	$(OBJCFLAGS)" OBJECTS="$(OBJECTS)" $(bindir)/make-h2x $@ .

grid/classes.h:
	if [ ! -x grid ]; then mkdir grid; fi
	cd grid; ln -s ../grid.xc classes.h

install:
	echo "no default install"
clean:
	- rm -f grid.x[cmt] *.o $(TARGETS_C) $(TARGETS_A) $(TARGETS_M) core
	- rm grid/classes.h; rmdir grid

c: $(TARGETS_C)
a: $(TARGETS_A)
m: $(TARGETS_M)

$(TARGETS_C): %: grid.o %.o $(OBJECTS)
	$(CC) $(LDFLAGS) $@.o $(OBJECTS) -o $@ $(LIBS_C)

$(TARGETS_A): %: grid.o %.o $(OBJECTS)
	$(CC) $(LDFLAGS) $@.o $(OBJECTS) -o $@ $(LIBS_A)

mousetraps: grid.o mousetraps.o Mousetrap.o
	$(CC) $(LDFLAGS) $@.o Mousetrap.o -o $@ $(LIBS_A)
mousetraps2: grid.o mousetraps2.o Mousetrap2.o
	$(CC) $(LDFLAGS) $@.o Mousetrap2.o -o $@ $(LIBS_A)


Example A-4. Mousetrap.h

#import <activity.h>
#import <defobj/Create.h>

@interface Mousetrap : CreateDrop
{
  int  xCoord;
  int  yCoord;
  int  triggered;
  id   displayWidget;
}
+		create: aZone setXCoord: (int)x setYCoord: (int)y;
- (int)		getXCoord;
- (int)		getYCoord;
- (void)	trigger;
- (BOOL)	getTriggered;
- (void)	printTriggered;
/*
-               setDisplayWidget: w;
*/
@end

@interface Grid2D : CreateDrop
{
  int  gridSize;
  id   *cells;      // array of gridSize X gridSize cells
}+		create: aZone setGridSize: (int)size;
- (int)		getGridSize;
-		atX: (int)xCoord atY: (int)yCoord;
- (void)	atX: (int)xCoord atY: (int)yCoord put: anObject;
@end

// global variables currently used as world parameters
//
extern int triggerLikelihood;
extern int numberOutputTriggers;
extern int maxTriggerDistance;
extern int maxTriggerTime;
extern int gridSize;
extern int printTriggerEvents;
extern int printSameTickTriggers;

// (trigger distance and trigger time are currently uncorrelated.)

// global variable containing root object for world (eventually in context?)
//
extern id grid;

Example A-5. Mousetrap.m

#import "Mousetrap.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>
#include <stdlib.h>

extern id  grid, worldSchedule;

extern unsigned  numTriggered;

@implementation Mousetrap

+ create: aZone setXCoord: (int)x setYCoord: (int)y
{
  Mousetrap  *newTrap;

  newTrap = [self create: aZone];
  newTrap->xCoord = x;
  newTrap->yCoord = y;
  return newTrap;
}

- (void) trigger
{
  int       n, xTrigger, yTrigger;
  unsigned  bits, xbits, ybits, tbits, currentTick, triggerTick;

  if ( ! triggered ) {

    currentTick = getCurrentTime();
    if ( printTriggerEvents ) {
      printf( "mousetrap at x: %.2d, y: %.2d triggered at time: %d\n",
              xCoord, yCoord, currentTick );
    }
    // nelson hacks
    // [displayWidget drawPointX: xCoord Y: yCoord Color: 2];
    numTriggered++;

    bits = rand();
    if ( ( ( bits & 0xff ) ) < triggerLikelihood ) {
      triggered = 1;

      for ( n = numberOutputTriggers; n > 0; n-- ) {
        bits = rand();
        xbits = bits & 0xff;
        ybits = bits >> 8 & 0xff;
        bits = rand();
        tbits = bits & 0xff;
        bits >>= 8;

	if ( bits & 1 ) {
	  xTrigger = ( xCoord + ( xbits & ( maxTriggerDistance - 1 ) ) )
                     % gridSize;
	} else {
	  xTrigger = ( xCoord - ( xbits & ( maxTriggerDistance - 1 ) )
                       + gridSize ) % gridSize;
	}
	if ( bits & 2 ) {
	  yTrigger = ( yCoord + ( ybits & (maxTriggerDistance - 1) ) )
                     % gridSize;
	} else {
	  yTrigger = ( yCoord - ( ybits & (maxTriggerDistance - 1) )
                       + gridSize ) % gridSize;
	}
        triggerTick = currentTick + ( tbits & (maxTriggerTime - 1) );

        if ( printSameTickTriggers && triggerTick == currentTick )
          printf( "triggering mousetrap at same timestep at time: %d\n",
                  currentTick );

	[worldSchedule at: triggerTick
          createActionTo: [grid atX: xTrigger atY: yTrigger]
          message: M( trigger )];
      }
    }
  }
}

- (int) getXCoord
{
  return xCoord;
}

- (int) getYCoord
{
  return yCoord;
}

- (BOOL) getTriggered
{
  return triggered;
}

- (void) printTriggered
{
  timeval_t  currentTime;

  currentTime = getCurrentTime();
  printf( "trigger status of mousetrap at x: %.2d, y: %.2d at time: %lu is %d\n",
             xCoord, yCoord, currentTime, triggered );
}

/*
- setDisplayWidget: w {
  displayWidget = w;
}
*/

@end


@implementation Grid2D

+ create: aZone setGridSize: (int)size
{
  Grid2D  *newGrid;

  newGrid = [aZone allocIVars: self];
  newGrid->gridSize = size;
  newGrid->cells = [aZone allocBlock:
                      newGrid->gridSize * newGrid->gridSize * sizeof (id)];
  return newGrid;
}

- (int) getGridSize
{
  return gridSize;
}

- atX: (int)xCoord atY: (int)yCoord
{
  return cells[ xCoord + yCoord * gridSize];
}

- (void) atX: (int)xCoord atY: (int)yCoord put: anObject
{
  cells[ xCoord + yCoord * gridSize] = anObject;
}

@end

Example A-6. Mousetrap2.m

#import "Mousetrap.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>
#include <stdlib.h>

extern id  grid, worldSchedule;

extern unsigned  numTriggered;

@implementation Mousetrap

+ create: aZone setXCoord: (int)x setYCoord: (int)y
{
  Mousetrap  *newTrap;

  newTrap = [self create: aZone];
  newTrap->xCoord = x;
  newTrap->yCoord = y;
  return newTrap;
}

- (void) trigger
{
  int       n, xTrigger, yTrigger;
  unsigned  bits, xbits, ybits, tbits, currentTick, ownerTick, triggerTick;
  id        subgroup, ownerActivity;

  if ( ! triggered ) {

    // get subclock schedule and its current time

    // (Could still have a concurrent group within the subclock schedule,
    // but the initial getCurrentScheduleActivity() will skip over this
    // to get the running activity of the subclock schedule.)

    ownerActivity = getCurrentScheduleActivity();
    currentTick   = [ownerActivity getCurrentTime];

    // get activity running the subclock schedule activity, and its time

    ownerActivity = [ownerActivity getOwnerActivity];
    ownerTick     = [ownerActivity getCurrentTime];

    if ( printTriggerEvents ) {
      printf( "mousetrap at x: %.2d, y: %.2d triggered at time: %d,%d\n",
              xCoord, yCoord, ownerTick, currentTick );
    }
    // nelson hacks
    // [displayWidget drawPointX: xCoord Y: yCoord Color: 2];
    numTriggered++;

    bits = rand();
    if ( ( ( bits & 0xff ) ) < triggerLikelihood ) {
      triggered = 1;

      for ( n = numberOutputTriggers; n > 0; n-- ) {
        bits = rand();
        xbits = bits & 0xff;
        ybits = bits >> 8 & 0xff;
        bits = rand();
        tbits = bits & 0xff;
        bits >>= 8;

	if ( bits & 1 ) {
	  xTrigger = ( xCoord + ( xbits & ( maxTriggerDistance - 1 ) ) )
                     % gridSize;
	} else {
	  xTrigger = ( xCoord - ( xbits & ( maxTriggerDistance - 1 ) )
                       + gridSize ) % gridSize;
	}
	if ( bits & 2 ) {
	  yTrigger = ( yCoord + ( ybits & (maxTriggerDistance - 1) ) )
                     % gridSize;
	} else {
	  yTrigger = ( yCoord - ( ybits & (maxTriggerDistance - 1) )
                       + gridSize ) % gridSize;
	}
        triggerTick = ( ownerTick * 10 ) + currentTick +
                        ( tbits & (maxTriggerTime - 1) );

        if ( printSameTickTriggers && triggerTick == currentTick )
          printf( "triggering mousetrap at same timestep at time: %d\n",
                  currentTick );

	subgroup = [worldSchedule insertGroup: (id)( triggerTick / 10 )];
        [subgroup
          at: (triggerTick % 10)
          createActionTo: [grid atX: xTrigger atY: yTrigger]
          message: M( trigger )];
      }
    }
  }
}

- (int) getXCoord
{
  return xCoord;
}

- (int) getYCoord
{
  return yCoord;
}

- (BOOL) getTriggered
{
  return triggered;
}

- (void) printTriggered
{
  timeval_t  currentTime;
  
  currentTime = getCurrentTime();
  printf("trigger status of mousetrap at x: %.2d, y: %.2d at time: %lu is %d\n",
         xCoord, yCoord, currentTime, triggered );
}

/*
- setDisplayWidget: w {
  displayWidget = w;
}
*/

@end


@implementation Grid2D

+ create: aZone setGridSize: (int)size
{
  Grid2D  *newGrid;

  newGrid = [aZone allocIVars: self];
  newGrid->gridSize = size;
  newGrid->cells = [aZone allocBlock:
                      newGrid->gridSize * newGrid->gridSize * sizeof (id)];
  return newGrid;
}

- (int) getGridSize
{
  return gridSize;
}

- atX: (int)xCoord atY: (int)yCoord
{
  return cells[ xCoord + yCoord * gridSize];
}

- (void) atX: (int)xCoord atY: (int)yCoord put: anObject
{
  cells[ xCoord + yCoord * gridSize] = anObject;
}

@end

Example A-7. grid.h

#import <collections.h>

@protocol GridTurtle <Create, Drop, CREATABLE>
- (void) move: (int)distance;
- (void) turn: (int)angle;     /* angle measured in units of pi/2 */
- (void) print;
@end

typedef enum direction { north, east, south, west } direction_t;

extern id <Symbol>  S1;

extern id <Warning> W1;

extern id <Error>   E1;

#import "grid.xt"

Example A-8. grid.m

#import "grid.xm"

void _grid_implement( void )
{
  initModule( collections );

  [id_GridTurtle_c setTypeImplemented: GridTurtle];
}

void _grid_initialize( void )
{
  defsymbol( S1 );
  defwarning( W1, 0 );
  deferror( E1, 0 );
}

Example A-9. grid0.m

#import "GridTurtle.h"

int main(void)
{
  id   aZone, t1;

  initModule( grid );

  aZone = [Zone create: globalZone];

  t1 = [GridTurtle create: aZone];
  [t1 drop];
  t1 = [GridTurtle create: aZone];
  [t1 move: 10];
  [t1 turn: -1];
  [t1 move: 10];
  [t1 print];

  [t1 turn: 23];
  [t1 move: 10];
  [t1 print];

  [aZone xprint];
  [aZone xfprint];
  [aZone drop];
  return 0;
}

Example A-10. grid1a.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id   aZone, anArray, newArray, aTurtle, aMember, index;
  int  i;
  
  initModule( grid );

  aZone = [Zone create: globalZone];

  anArray = [Array create: aZone setCount: 12];

  printf( "count: %d\n", [anArray getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [anArray atOffset: i put: aTurtle];
  }

  printf( "count: %d\n", [anArray getCount] );

  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) || [index getLoc] != End ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  while ( (aMember = [index prev]) || [index getLoc] != Start ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  [anArray setCount: 15];
  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) || [index getLoc] != End ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  [index setLoc: Start];

  [anArray setCount: 8];
  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) || [index getLoc] != End ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  [anArray atOffset: 2 put: nil];
  newArray = [anArray copy: aZone];

  index = [newArray begin: scratchZone];
  [newArray atOffset: 3 put: nil];
  while ( (aMember = [index next]) || [index getLoc] != End ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  [newArray drop];

  [anArray atOffset: 5 put: nil];
  newArray = [Array createBegin: aZone];
  [newArray setInitialValue: anArray];
  newArray = [newArray createEnd];
  [newArray atOffset: 6 put: nil];

  index = [newArray begin: scratchZone];
  while ( (aMember = [index next]) || [index getLoc] != End ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  [index drop];

  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) || [index getLoc] != End ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  for ( i = 0; i < 8; i++ ) {
    aMember = [anArray atOffset: i];
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  [anArray xprint];
  [aZone xprint];
  [anArray drop];
  [newArray drop];
  [aZone xprint];
  [aZone xfprint];
  [aZone drop];
  exit(0);
}

Example A-11. grid1b.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id   aZone, anArray, aTurtle, aMember, index;
  int  i;
  
  initModule( grid );

  aZone = [Zone create: globalZone];

  anArray = [Array createBegin: aZone];
  [anArray setCount: 12];
  [anArray setDefaultMember: Member];
  anArray = [anArray createEnd];

  printf( "count: %d\n", [anArray getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [anArray atOffset: i put: aTurtle];
  }

  printf( "count: %d\n", [anArray getCount] );

  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  while ( (aMember = [index prev]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  [anArray setCount: 15];
  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  [index setLoc: Start];

  [anArray setCount: 8];
  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  for ( i = 0; i < 8; i++ ) {
    [[anArray atOffset: i] print];
  }
  [anArray xprint];
  [anArray drop];
  [aZone xprint];
  [aZone drop];
  exit(0);
}

Example A-12. grid1c.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id   aZone, anArray, aTurtle, aMember, index, newArray;
  int  i;
  
  initModule( grid );

  aZone = [Zone create: globalZone];

  anArray = [Array createBegin: aZone];
  [anArray setCount: 10];
  [anArray setDefaultMember: Member];
  anArray = [anArray createEnd];

  printf( "count: %d\n", [anArray getCount] );

  for ( i = 0; i < 5; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [anArray atOffset: i put: aTurtle];
  }

  printf( "count: %d\n", [anArray getCount] );

  index = [anArray begin: scratchZone];
  while ( (aMember = [index next]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  newArray = [Array createBegin: aZone];
  [newArray setMemberBlock: (id *)[anArray getMemberBlock] + 2 setCount: 6];
  newArray = [newArray createEnd];

  index = [newArray begin: scratchZone];
  while ( (aMember = [index next]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }

  [newArray setMemberBlock: [anArray getMemberBlock] setCount: 6];

  index = [newArray begin: scratchZone];
  while ( (aMember = [index next]) ) {
    if ( ! aMember ) {
      printf( "member is nil\n" );
    } else if ( [aMember respondsTo: M(print)] ) {
      [aMember print];
    } else {
      printf( "%s\n", [aMember getName] );
    }
  }
  [newArray xprint];
  [anArray drop];
  [newArray drop];
  [aZone xprint];
  [aZone drop];
  exit(0);
}

Example A-13. grid2.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

#import <collections/List_linked.h>
#import <defobj/defalloc.h>

extern id _obj_sessionZone;  // to confirm cleanup of display names

@interface MyList : List_linked
+ create: aZone;
@end

@implementation MyList

+ create: aZone
{
  List_linked  *newList;

  newList = [aZone allocIVars: [List_linked self]];
  setMappedAlloc( newList );
  return newList;
}

@end

int main(void)
{
  id    aZone, aList, aTurtle, index, newList;
  int   i;
  char  buffer[50];

  initModule( grid );

  aZone = [Zone create: globalZone];
  aList = [MyList create: aZone];

  printf( "count: %d\n", [aList getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [aList addLast: aTurtle];
    if ( i % 2 ) {
      sprintf( buffer, "turtle number %d", i );
      [aTurtle setDisplayName: buffer];
    }
  }

  printf( "count: %d\n", [aList getCount] );

  printf( "\n[aZone xfprintid]\n" );
  [aZone xfprintid];
  printf( "\n" );

  index = [aList begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  [index drop];

  [aList addFirst: [aList removeLast]];
  [aList addFirst: [aList removeLast]];
  [aList addLast: [aList removeFirst]];

  printf( "count: %d\n", [aList getCount] );
  index = [aList begin: scratchZone];
  for ( [index setLoc: End]; (aTurtle = [index prev]); ) {
    [aTurtle print];
  }

  printf( "turtle located at offset 3: " );
  [[index setOffset: 3] print];
  printf( "turtle removed at offset 3: " );
  [[index remove] print];

  [index setLoc: Start];
  while ( (aTurtle = [index next]) );

  [aList forEach: @selector( print )];

  newList = [List createBegin: aZone];
  [newList setInitialValue: aList];
  newList = [newList createEnd];
  [aList drop];

  printf( "new list count: %d\n", [newList getCount] );
  [newList forEach: @selector( print )];

  aList = [newList copy: aZone];
  printf( "copied list count: %d\n", [aList getCount] );
  [aList forEach: @selector( print )];

  printf( "\nsession zone before drop of all turtles\n" );
  [_obj_sessionZone xprint];
  [aList deleteAll];
  [aList drop];

  printf( "\nsession zone after drop\n" );
  [_obj_sessionZone xprint];
  printf( "\n" );

  [newList drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-14. grid2b.m

// This is an old test program for safe indexes mode on a list, which is
// not currently supported.  Now it shows how indexes can be affected by
// remove.

#import "grid.h"
#import "GridTurtle.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id   aZone, listType, aList, aTurtle, index, index2;
  int  i;
  
  initModule( grid );

  aZone = [Zone create: globalZone];

  listType = [List customizeBegin: aZone];
  [listType setIndexFromMemberLoc: offsetof( GridTurtle_c, listMembership )];
  // [listType setSafeIndexes: 1];
  listType = [listType customizeEnd];

  aList = [listType create: aZone];

  printf( "count: %d\n", [aList getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [aList addLast: aTurtle];
  }

  printf( "count: %d\n", [aList getCount] );

  index = [aList begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  [index drop];

  [aList addFirst: [aList removeLast]];
  [aList addFirst: [aList removeLast]];
  [aList addLast: [aList removeFirst]];

  index = [aList begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  [aList addLast: [aList removeFirst]];

  printf( "count: %d\n", [aList getCount] );
  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 8]];
  printf( "offset after createIndex:fromMember: %d\n", [index getOffset] );
  [index next];
  [index next];
  [index prev];
  printf( "offset after next to End then prev: %d\n", [index getOffset] );

  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 1]];
  [index setOffset: 1];
  index2 = [aList createIndex: scratchZone fromMember: [aList atOffset: 0]];
  [index remove];
  [index2 remove];
  printf( "offset after remove on both index and lesser index: %d\n",
          [index getOffset] );
  printf( "member after removed offsets 0 and 1:\n  " );
  [[index next] print];

  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 0]];
  index2 = [aList createIndex: scratchZone fromMember: [aList atOffset: 1]];
  [index remove];
  [index2 remove];
  printf( "offset after remove on both index and greater index: %d\n",
          [index getOffset] );
  printf( "member after removed offsets 0 and 1:\n  " );
  [[index next] print];

  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 1]];
  index2 = [aList createIndex: scratchZone fromMember: [aList atOffset: 0]];
  [index2 remove];
  printf( "offset after remove on lesser index: %d\n",
          [index getOffset] );
  printf( "member after removed offset 0 and original offset 1:\n  " );
  [[index next] print];

  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 1]];
  index2 = [aList createIndex: scratchZone fromMember: [aList atOffset: 1]];
  [index2 remove];
  printf( "offset after remove on same index: %d\n",
          [index getOffset] );
  printf( "member after removed offset 1:\n  " );
  [[index next] print];

  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 0]];
  index2 = [aList createIndex: scratchZone fromMember: [aList atOffset: 1]];
  [index2 remove];
  printf( "offset after remove on greater index: %d\n",
          [index getOffset] );
  printf( "member after original offset 0 and removed offset 1:\n  " );
  [[index next] print];

  index = [aList createIndex: scratchZone fromMember: [aList atOffset: 0]];
  [index setLoc: Start];
  index2 = [aList createIndex: scratchZone fromMember: [aList atOffset: 0]];
  [index2 remove];
  printf( "offset after move to Start and remove on other index: %d\n",
          [index getOffset] );
  printf( "member after removed offset 0:\n  " );
  [[index next] print];

  printf( "remaining members of list:\n" );
  index = [aList begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  printf( "location of index at End: %s\n", [[index getLoc] getName] );

  [index setOffset: 1];
  printf( "location of index at offset 1: %s\n", [[index getLoc] getName] );
  [index remove];
  printf( "location of index after remove: %s\n", [[index getLoc] getName] );
  [index prev];
  printf( "location of index after prev: %s\n", [[index getLoc] getName] );

  [index setOffset: 0];
  printf( "location of index at offset 0: %s\n", [[index getLoc] getName] );
  [index remove];
  printf( "location of index after remove: %s\n", [[index getLoc] getName] );
  [index next];
  printf( "location of index after next: %s\n", [[index getLoc] getName] );

  [aList xprint];
  [aList drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-15. grid3.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id    aZone, aMap, aTurtle, key, index;
  int   i;
  char  buffer[10];

  initModule( grid );

  aZone = [Zone create: globalZone];
  aMap  = [Map create: aZone];

  printf( "count: %d\n", [aMap getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    sprintf( buffer, "%d", i );
    key = [String create: aZone setC: buffer];
    [aMap at: key insert: aTurtle];
  }

  printf( "count: %d\n", [aMap getCount] );

  index = [aMap begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    key = [index getKey];
    printf( "%s: ", [key getC] );
    [aTurtle print];
    [key drop];
  }

  [[aMap getFirst] print];
  [[aMap getLast] print];

  [aMap xprint];
  [aMap drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-16. grid3b.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id   aZone, aMap, aTurtle, index;
  int   i;

  initModule( grid );

  aZone = [Zone create: globalZone];
  aMap  = [Map createBegin: aZone];
  [aMap setCompareFunction: compareIntegers];
  aMap = [aMap createEnd];

  printf( "count: %d\n", [aMap getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    [aTurtle turn: -1];
    [aTurtle move: (10 - i) * 10];
    [aMap at: (id)(10 - i) insert: aTurtle];
  }

  printf( "count: %d\n", [aMap getCount] );

  index = [aMap begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    printf( "%d: ", (int)[index getKey] );
    [aTurtle print];
  }
  [index drop];

  [[aMap getFirst] print];
  [[aMap getLast] print];

  [aMap xprint];
  [aMap drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-17. grid4.m

#import "grid.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id aZone, aSet, aTurtle, turtles[10], index;
  int i;

  initModule( grid );

  aZone = [Zone create: globalZone];
  aSet  = [Set create: aZone];

  printf( "count: %d\n", [aSet getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    turtles[i] = aTurtle;
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    if ( i & 1 ) [aSet add: aTurtle];
  }

  printf( "count: %d\n", [aSet getCount] );

  index = [aSet begin: aZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  for ( i = 0; i < 10; i++ ) {
    if ( [aSet at: turtles[i]] != turtles[i] ) {
      printf( "turtle not found at %d\n", i );
    }
  }

  for ( i = 0; i < 10; i++ ) {
    if ( i & 1 ) {
      [aSet remove: turtles[i]];
    } else {
      [aSet add: turtles[i]];
    }
  }
  index = [aSet begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  for ( i = 0; i < 10; i++ ) {
    if ( [aSet at: turtles[i]] != turtles[i] ) {
      printf( "turtle not found at %d\n", i );
    }
  }
  [index drop];

  [aSet xprint];
  [aSet drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-18. grid4b.m

#import "grid.h"
#import "GridTurtle.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main(void)
{
  id   aZone, anOrderedSet, aTurtle, turtles[10], index;
  int  i;

  initModule( grid );

  aZone = [Zone create: globalZone];

  anOrderedSet = [OrderedSet createBegin: aZone];
  [anOrderedSet setIndexFromMemberLoc:
    offsetof( GridTurtle_c, listMembership )];
  anOrderedSet = [anOrderedSet createEnd];

  printf( "count: %d\n", [anOrderedSet getCount] );

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: aZone];
    turtles[i] = aTurtle;
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    if ( i & 1 ) [anOrderedSet add: aTurtle];
  }

  printf( "count: %d\n", [anOrderedSet getCount] );

  index = [anOrderedSet begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  for ( i = 0; i < 10; i++ ) {
    if ( ! [anOrderedSet contains: turtles[i]] ) {
      printf( "turtle not found at %d\n", i );
    }
  }

  for ( i = 0; i < 10; i++ ) {
    if ( i % 2 ) {
      [anOrderedSet remove: turtles[i]];
    } else {
      [anOrderedSet add: turtles[i]];
    }
  }
  index = [anOrderedSet begin: scratchZone];
  while ( (aTurtle = [index next]) ) {
    [aTurtle print];
  }
  for ( i = 0; i < 10; i++ ) {
    if ( ! [anOrderedSet contains: turtles[i]] ) {
      printf( "turtle not found at %d\n", i );
    }
  }

  [anOrderedSet xprint];
  [anOrderedSet drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-19. grid5.m

#import "grid.h"
#import <activity.h>

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

static BOOL trace( id anActivity );

int main(void)
{
  id   aZone, aList, aTurtle;
  id   emptyActions, moveActions, printActions, moveAndPrint;
  id   groupActivity, swarm, swarmActivity, status;
  int  i, stepCount;

  initModule( grid );
  initModule( activity );

  aZone = [Zone create: globalZone];
  swarm = [SwarmProcess create: aZone];
  _activity_zone = [Zone create: globalZone];

  [_activity_zone xprint];
  swarmActivity = [swarm activateIn: nil];
  [swarmActivity drop];
  [_activity_zone xprint];

  //  if ( _obj_debug ) exit(0);

  aList = [List create: swarm];

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: swarm];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [aTurtle turn: 1];
    [aList addLast: aTurtle];
  }

  emptyActions = [ActionGroup create: swarm];

  moveActions = [ActionGroup create: swarm];
  for ( i = 0; i < 10; i++ ) {
    if ( i % 2 )
      [moveActions
        createActionTo: [aList atOffset: i] message: M(move:) : (id)10 ];
  }

  printActions = [ActionGroup create: swarm];
  for ( i = 0; i < 10; i++ ) {
    [printActions createActionTo: [aList atOffset: i] message: M(print)];
  }

  moveAndPrint = [ActionGroup create: swarm];
  [moveAndPrint createAction: emptyActions];
  [moveAndPrint createAction: moveActions];
  [moveAndPrint createAction: printActions];
  for ( i = 0; i < 10; i++ ) {
    if ( i % 2 )
      [moveAndPrint
        createActionTo: [aList atOffset: i] message: M(move:) : (id)10];
  }
  [moveAndPrint createActionForEach: aList message: M(print)];

  groupActivity = [moveAndPrint activateIn: nil];
  printf("about to start schedule\n");
  while ( (status = [groupActivity run]) != Completed );
  printf( "run return status: %s\n\n", [status getName] );
  [groupActivity drop];

  swarmActivity = [swarm activateIn: nil];
  [swarm activate: moveAndPrint];

  if ( swarmActivity != [swarm getSwarmActivity] )
    raiseEvent( WarningMessage, nil );

  _activity_trace = trace;

  for ( stepCount = 1; [swarmActivity step] == Stopped; stepCount++ );
  printf( "number of steps: %d\n", stepCount );

  [swarmActivity drop];
  [_activity_zone xprint];

  [emptyActions drop];
  [moveActions drop];
  [printActions drop];
  [moveAndPrint drop];
  [aList deleteAll];
  [aList drop];
  [[swarm getInternalZone] xprint];

  [swarm drop];
  [aZone xprint];
  return 0;
}

static BOOL trace( id anActivity )
{
  char  buffer[100];

  if ( getCurrentAction() ) {
    _obj_formatIDString( buffer, getCurrentAction() );
    printf( "action trace: %s\n", buffer );
  } else {
    printf( "action trace: activity status %s\n",
      [[anActivity getStatus] getName] );
  }
  return 0;
}

Example A-20. grid6.m

#import "grid.h"
#import <activity.h>
#import <activity/SwarmProcess.h> // for activate: call
#import <defobj/DefObject.h>      // for dropAllocations: of internal actions

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

static void terminateFunction( void )
{
  [getTopLevelActivity() terminate];
}

static void nestedFunction( void )
{
  char buf1[100], buf2[100];

  _obj_formatIDString( buf1, getTopLevelActivity() );
  _obj_formatIDString( buf2, [getTopLevelActivity() getControllingActivity] );

  printf( "top level activity: %s\ncontrolling activity: %s\n", buf1, buf2 );
}

static void runFunction( void )
{
  id  group, groupActivity;

  group = [ActionGroup create: globalZone];
  [group createActionCall: (func_t)printf : (id)"nested group performed\n"];
  [group createActionCall: nestedFunction];
  groupActivity = [group activateIn: nil];
  [groupActivity run];
  [groupActivity drop];
  [group drop];
}

int main(void)
{
  id  x, aZone, sched1, sched2, action1, action2;
  id  swarm, swarmActivity, status;

  initModule( grid );
  initModule( activity );

  aZone = [Zone create: globalZone];
  swarm = [SwarmProcess create: aZone];
  _activity_zone = [Zone create: globalZone];

  sched1 = [Schedule create: swarm];
  [sched1 at: 1 createActionCall: terminateFunction];

  x = [Schedule createBegin: swarm];
  [x setRepeatInterval: 10];
  sched2 = [x createEnd];

  [sched2 createActionCall: (func_t)printf :
    (id)"repeating action performed\n"];
  [sched2 createActionCall: (func_t)runFunction];

  // create a concurrent group just to make sure it goes away

  action1 = [sched2 at: 1 createActionCall: (func_t)printf : (id)"action 1\n"];
  action2 = [sched2 at: 1 createActionCall: (func_t)printf : (id)"action 2\n"];

  [sched2 remove: action1];
  [sched2 remove: action2];

  swarmActivity = [swarm activateIn: nil];
  [swarm activate: sched1];
  [swarm activate: sched2];

  while ( (status = [swarmActivity run]) != Stopped && status != Completed );

  [swarmActivity drop];
  [_activity_zone xprint];

  [sched1 drop];
  [sched2 drop];
  [action1 drop];
  [action2 drop];
  [[swarm getInternalZone] xprint];

  [swarm drop];
  [aZone xprint];
  return 0;
}

Example A-21. grid7.m

#import "grid.h"
#import <activity.h>
#import <activity/XActivity.h>

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

extern BOOL respondsTo( id, SEL );  // from defobj

static BOOL trace( id anActivity );

static id newTurtle( void )
{
  id          aTurtle;
  static int  ycoord;

  aTurtle = [GridTurtle create: globalZone];
  [aTurtle move: ++ycoord];
  return aTurtle;
}

int main(void)
{
  id   aZone, aList, aTurtle;
  id   emptyActions1, emptyActions2;
  id   moveAndPrint, moveActions, printActions;
  id   printRelative, printRepeat, startSchedule;
  id   swarm, swarmActivity, status;
  int  i;

  initModule( grid );
  initModule( activity );

  aZone = [Zone create: globalZone];
  swarm = [SwarmProcess create: aZone];
  _activity_zone = [Zone create: globalZone];

  aList = [List create: swarm];

  for ( i = 0; i < 10; i++ ) {
    aTurtle = [GridTurtle create: swarm];
    [aTurtle turn: -1];
    [aTurtle move: i * 10];
    [aTurtle turn: 1];
    [aList addLast: aTurtle];
  }

  moveActions = [ActionGroup create: swarm];
  for ( i = 0; i < 10; i++ ) {
    if ( i % 2 )
      [moveActions
        createActionTo: [aList atOffset: i] message: M(move:) : (id)10 ];
  }

  printActions = [ActionGroup create: swarm];
  for ( i = 0; i < 10; i++ ) {
    [printActions createActionTo: [aList atOffset: i] message: M(print)];
  }

  moveAndPrint = [Schedule createBegin: swarm];
  [moveAndPrint setRepeatInterval: 10];
  moveAndPrint = [moveAndPrint createEnd];

  [moveAndPrint at: 0 createAction: moveActions];
  [moveAndPrint at: 0 createAction: printActions];

  emptyActions1 = [ActionGroup create: swarm];
  emptyActions2 = [ActionGroup create: swarm];

  printRelative = [Schedule createBegin: swarm];
  [printRelative setRelativeTime: 1];
  printRelative = [printRelative createEnd];

  [printRelative at: 0 createActionTo: newTurtle() message: M(print)];
  [printRelative at: 4 createAction: emptyActions1];
  [printRelative at: 4 createActionTo: newTurtle() message: M(print)];
  [printRelative at: 9 createActionTo: newTurtle() message: M(print)];

  printRepeat = [Schedule createBegin: swarm];
  [printRepeat setRepeatInterval: 10];
  printRepeat = [printRepeat createEnd];

  [printRepeat at: 0 createActionTo: newTurtle() message: M(print)];
  [printRepeat at: 1 createActionTo: newTurtle() message: M(print)];

  startSchedule = [Schedule create: swarm];
  [startSchedule at: 1 createAction: printRepeat];
  [startSchedule at: 2 createActionTo: newTurtle() message: M(print)];
  [startSchedule at: 2 createAction: emptyActions2];

  [startSchedule at: 2 createAction: printRelative];
  [startSchedule at: 18 createAction: printRelative];
  [startSchedule at: 21 createAction: printRelative];
  [startSchedule at: 34 createAction: printRelative];

  [startSchedule at: 5 createActionTo: newTurtle() message: M(print)];
  [startSchedule at: 12 createActionTo: newTurtle() message: M(print)];
  [startSchedule at: 18 createActionTo: newTurtle() message: M(print)];
  [startSchedule at: 10 createActionTo: newTurtle() message: M(print)];
  [startSchedule at: 20 createActionTo: newTurtle() message: M(print)];

  _activity_trace = trace;
  swarmActivity = [swarm activateIn: nil];
  [swarm activate: startSchedule];

  while ( (status = [swarmActivity run]) != Stopped && status != Completed );
  printf( "run return status: %s\n", [status getName] );

  [swarmActivity drop];
  [_activity_zone xprint];

  [moveActions drop];
  [printActions drop];
  [moveAndPrint drop];
  [emptyActions1 drop];
  [emptyActions2 drop];

  [printRelative drop];
  [printRepeat drop];
  [startSchedule drop];

  [aList deleteAll];
  [aList drop];
  [[swarm getInternalZone] xprint];
  [swarm drop];
  return 0;
}

static BOOL trace( id anActivity )
{
  id         swarmActivity, string;
  int        level;
  timeval_t  currentTime = 999999;
  char       buffer[100];

  for ( swarmActivity = anActivity, level = 0;
        ! respondsTo( swarmActivity, @selector( getSynchronizationSchedule ) );
        swarmActivity = [swarmActivity getOwnerActivity], level++ );

  currentTime = getCurrentTime();

  if ( swarmActivity != getCurrentSwarmActivity() ||
       currentTime != [getCurrentScheduleActivity() getCurrentTime] )
    raiseEvent( SourceMessage, "context macro mismatch\n" );

  _obj_formatIDString( buffer, anActivity );
  if ( [anActivity getStatus] == Running ) {
    [getCurrentAction() describe: (string = [String create: scratchZone])];
    printf( "at time: %lu, level %d, %s, %s",
             currentTime, level, buffer, [string getC] );
    [string drop];
  } else {
    printf( "at time: %lu, level %d, %s is %s\n",
             currentTime, level, buffer, [[anActivity getStatus] getName] );
  }
  if ( currentTime < 100 ) return 0;
  ((Activity_c *)anActivity)->status = Stopped;
  return 1;
}

Example A-22. grid8.m

#import "grid.h"
#import <activity/SwarmProcess.h>
#import <activity.h>

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

static void terminateFunction( void )
{
  [getTopLevelActivity() terminate];
}

static void stopFunction( void )
{
  printf( "stopping activity at time: %lu\n", getCurrentTime() );
  [getTopLevelActivity() stop];
}

int main(void)
{
  id   aZone, aTurtle;
  id   simSched1, simSched2, displaySchedule, terminateSchedule;
  id   simSwarm, obsSwarm, obsSwarmActivity;

  // initialize

  initModule( grid );
  initModule( activity );

  aZone = [Zone create: globalZone];
  obsSwarm = [SwarmProcess create: aZone];
  simSwarm = [SwarmProcess create: obsSwarm];

  _activity_zone = [Zone create: globalZone];

  // create a turtle to turn and move during simulation

  aTurtle = [GridTurtle create: simSwarm];

  // create a pair of simulation schedules (repeat intervals of 2 and 4)

  simSched1 = [Schedule createBegin: simSwarm];
  [simSched1 setRepeatInterval: 2];
  simSched1 = [simSched1 createEnd];
  [simSched1 at: 0 createActionTo: aTurtle message: M(move:) : (id)10];

  simSched2 = [Schedule createBegin: simSwarm];
  [simSched2 setRepeatInterval: 4];
  simSched2 = [simSched2 createEnd];
  [simSched2 at: 0 createActionTo: aTurtle message: M(turn:) : (id)1];

  // create a display schedule to print turtle at every time step

  displaySchedule = [Schedule createBegin: obsSwarm];
  [displaySchedule setRepeatInterval: 1];
  displaySchedule = [displaySchedule createEnd];
  [displaySchedule at: 0 createActionTo: aTurtle message: M(print)];

  // create a schedule to terminate all activity at timestep 32

  terminateSchedule = [Schedule create: obsSwarm];
  [terminateSchedule at: 8 createActionCall: stopFunction];
  [terminateSchedule at: 11 createActionCall: terminateFunction];

  obsSwarmActivity = [obsSwarm activateIn: nil];
  [obsSwarm activate: terminateSchedule];
  [obsSwarm activate: displaySchedule];

  [obsSwarm activate: simSwarm];
  [simSwarm activate: simSched1];
  [simSwarm activate: simSched2];

  // run the top-level swarm to completion

  while ( [obsSwarmActivity next] != Completed );

  [obsSwarmActivity drop];
  [_activity_zone xprint];

  [aTurtle drop];
  [simSched1 drop];
  [simSched2 drop];
  [simSwarm drop];
  [displaySchedule drop];
  [terminateSchedule drop];

  [[obsSwarm getInternalZone] xprint];
  [[obsSwarm getInternalZone] xfprint];
  [obsSwarm drop];

  [aZone xprint];
  [aZone drop];
  return 0;
}

Example A-23. grid9.m

#import "grid.h"
#import <activity.h>
#import <activity/SwarmProcess.h>

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

static void testTerminate( timeval_t terminateTime )
{
  if ( getCurrentTime() >= terminateTime )
    [getTopLevelActivity() terminate];
}

@interface MySwarm : CSwarmProcess
{
  int  myVar;
}
- (void) setMyVar: (int)value;
- (void) printMyVar;
@end

@implementation MySwarm

- (void) setMyVar: (int)value
{
  myVar = value;
}

- (void) printMyVar
{
  printf( "value is %d\n", myVar );
}

@end

int main(void)
{
  id   aZone, aTurtle;
  id   simSched1, action1, action2, action3, moveGroup;
  id   simSched2, displaySchedule, terminateSchedule;
  id   displaySwarm, simSwarm, swarmActivity;

  // initialize

  initModule( grid );
  initModule( activity );

  aZone = [Zone create: globalZone];
  displaySwarm = [SwarmProcess create: aZone];
  simSwarm = [MySwarm create: displaySwarm];
  _activity_zone = [Zone create: globalZone];

  // create a turtle to turn and move during simulation

  aTurtle = [GridTurtle create: simSwarm];

  // create a pair of simulation schedules (repeat intervals of 2 and 4)

  simSched1 = [Schedule createBegin: simSwarm];
  [simSched1 setRepeatInterval: 2];
  simSched1 = [simSched1 createEnd];
  action1 = [simSched1 at: 0 createActionTo: aTurtle message: M(move:):(id)10];
  moveGroup = [ActionGroup create: simSwarm];
  action2 = [moveGroup createActionTo: aTurtle message: M(move:) : (id)-5];
  [simSched1 at: 0 createAction: moveGroup];
  [simSched1 at: 0 createActionCall: (func_t)testTerminate : (id)20];

  simSched2 = [Schedule createBegin: simSwarm];
  [simSched2 setRepeatInterval: 4];
  simSched2 = [simSched2 createEnd];
  [simSched2 at: 0 createActionTo: aTurtle message: M(turn:) : (id)1];
  action3 = [simSched2 at: 0 createActionCall: (func_t)testTerminate : (id)10];

  // create a display schedule to print turtle at every time step

  displaySchedule = [Schedule createBegin: displaySwarm];
  [displaySchedule setRepeatInterval: 1];
  displaySchedule = [displaySchedule createEnd];
  [displaySchedule createActionTo: aTurtle message: M(print)];

  // create a schedule to terminate after a while

  terminateSchedule = [Schedule create: displaySwarm];
  [terminateSchedule at: 10
    createActionTo: moveGroup message: M(remove:) : action2];
  [terminateSchedule at: 4
    createActionTo: simSched2 message: M(remove:) : action3];
  [terminateSchedule at: 16 createActionCall: (func_t)testTerminate : (id)16];

  // activate top-level swarm

  swarmActivity = [displaySwarm activateIn: nil];

  // manipulate custom swarm and then activate it

  [simSwarm setMyVar: 99];
  [simSwarm printMyVar];

  [simSwarm activateIn: displaySwarm];
  [[[simSwarm getSwarmActivity] getSwarm] printMyVar];

  // activate simulation schedules in simulation swarm

  [simSched1 activateIn: simSwarm];
  [simSched2 activateIn: simSwarm];

  // activate display schedules to mix in with simulation swarm

  [displaySchedule activateIn: displaySwarm];
  [terminateSchedule activateIn: displaySwarm];

  // run the top-level swarm to completion

  while ( [swarmActivity next] != Completed );

  [swarmActivity drop];
  [_activity_zone xprint];
  return 0;
}

Example A-24. mousetraps.m

#import "Mousetrap.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>


int gridSize              = 40;
int printTriggerEvents    = 1;
int printSameTickTriggers = 0;


// simulation parameters (these need to be a power of 2)

int triggerLikelihood    = 256;
int numberOutputTriggers = 2;
int maxTriggerDistance   = 4;
int maxTriggerTime       = 16;

// data from the mousetrap world

unsigned numTriggered = 0;

id grid, worldSchedule;

static void testTerminate( void )
{
  if ( ! [worldSchedule getCount] ) [getTopLevelActivity() terminate];
}

int main(int argc, char ** argv)
{
  id   aMousetrap, worldSwarm;
  id   displaySchedule, observerSwarm, observerActivity, status;
  int  x, y, stepCount;

  initModule( activity );

  observerSwarm = [SwarmProcess create: globalZone];
  worldSwarm = [SwarmProcess create: observerSwarm];
  _activity_zone = [Zone create: globalZone];

  // put a mousetrap on every grid point

  grid = [Grid2D create: worldSwarm setGridSize: gridSize];
  for ( y = 0; y < gridSize; y ++ ) {
    for ( x = 0; x < gridSize; x++ ) {
      aMousetrap = [Mousetrap create: worldSwarm setXCoord: x setYCoord: y];
      [grid atX: x atY: y put: aMousetrap];
    }
  }

  // create the mousetrap world schedule and schedule its first action

  worldSchedule = [Schedule createBegin: worldSwarm];
  [worldSchedule setAutoDrop: 1];
  worldSchedule = [worldSchedule createEnd];

  aMousetrap = [grid atX: gridSize/2 atY: gridSize/2];
  [worldSchedule at: 0 createActionTo: aMousetrap message: M(trigger)];

  // create display schedule and schedule the display events

  displaySchedule = [Schedule createBegin: observerSwarm];
  [displaySchedule setRepeatInterval: 10];
  displaySchedule = [displaySchedule createEnd];

  [displaySchedule at: 0 createActionTo:
    [grid atX: (gridSize + gridSize/2)/(gridSize/2) atY: gridSize/2]
    message: M(printTriggered)];
  [displaySchedule at: 0 createActionCall: (func_t)testTerminate];

  // create a swarm to combine the display schedule and the world swarm

  observerActivity = [observerSwarm activateIn: nil];
  [displaySchedule activateIn: observerSwarm];

  [worldSwarm activateIn: observerSwarm];
  [worldSchedule activateIn: worldSwarm];

  // [observerActivity run];

  status = [observerActivity stepUntil: 12];
  printf( "returned from stepUntil: 12 with status %s\n", [status getName] );
  status = [observerActivity stepUntil: 2];
  printf( "returned from stepUntil: 2 with status %s\n", [status getName] );

  for ( stepCount = 0; [observerActivity step] == Stopped; stepCount++ );
  printf( "number of steps: %d\n", stepCount );
  printf( "total number of mousetraps triggered: %d\n", numTriggered );
  return 0;
}

Example A-25. mousetraps2.m

#import "Mousetrap.h"

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>


int gridSize              = 40;
int printTriggerEvents    = 1;
int printSameTickTriggers = 0;


// simulation parameters (these need to be a power of 2)

int triggerLikelihood    = 256;
int numberOutputTriggers = 2;
int maxTriggerDistance   = 4;
int maxTriggerTime       = 16;

// data from the mousetrap world

unsigned numTriggered = 0;

id grid, worldSchedule;

static void testTerminate( void )
{
  int  remainingCount;

  remainingCount = [worldSchedule getCount];
  if ( ! [worldSchedule getCount] ) [getTopLevelActivity() terminate];
}

int main(int argc, char ** argv)
{
  id   aZone, aMousetrap, subschedType, subgroup;
  id   displaySchedule, observerSwarm, observerActivity;
  id   worldSwarm, worldActivity;
  int  x, y, stepCount;

  initModule( activity );

  aZone = globalZone;

  // put a mousetrap on every grid point

  grid = [Grid2D create: aZone setGridSize: gridSize];
  for ( y = 0; y < gridSize; y ++ ) {
    for ( x = 0; x < gridSize; x++ ) {
      aMousetrap = [Mousetrap create: aZone setXCoord: x setYCoord: y];
      [grid atX: x atY: y put: aMousetrap];
    }
  }

  // create the mousetrap world schedule and schedule its first action

  subschedType = [ConcurrentSchedule customizeBegin: aZone];
  [subschedType setAutoDrop: 1];
  subschedType = [subschedType customizeEnd];

  worldSchedule = [Schedule createBegin: aZone];
  [worldSchedule setAutoDrop: 1];
  [worldSchedule setConcurrentGroupType: subschedType];
  worldSchedule = [worldSchedule createEnd];

  aMousetrap = [grid atX: gridSize/2 atY: gridSize/2];
  subgroup = [worldSchedule insertGroup: (id)0];
  [subgroup at: 0 createActionTo: aMousetrap message: M(trigger)];

  // create display schedule and schedule the display events

  displaySchedule = [Schedule createBegin: aZone];
  [displaySchedule setRepeatInterval: 1];
  displaySchedule = [displaySchedule createEnd];

  [displaySchedule at: 0 createActionTo:
    [grid atX: (gridSize + gridSize/2)/(gridSize/2) atY: gridSize/2]
    message: M(printTriggered)];
  [displaySchedule at: 0 createActionCall: (func_t)testTerminate];

  // create a swarm to combine the display schedule and the world swarm

  observerSwarm = [SwarmProcess create: aZone];
  observerActivity = [observerSwarm activateIn: nil];
  [displaySchedule activateIn: observerSwarm];

  worldSwarm = [SwarmProcess create: aZone];
  worldActivity = [worldSwarm activateIn: observerSwarm];
  subgroup = [worldSchedule activateIn: worldSwarm];

  // [observerActivity run];
  for ( stepCount = 0; [observerActivity step] == Stopped; stepCount++ );
  printf( "number of steps: %d\n", stepCount );
  printf( "total number of mousetraps triggered: %d\n", numTriggered );
  return 0;
}

Example A-26. strtest.m

#import <collections.h>

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

int main( void )
{
  id  aZone, s1, s2, s3, t1, FooBarString, s4;

  initModule( collections );

  aZone = [Zone create: globalZone];

  t1 = [String customizeBegin: aZone];
  [t1 setC: "foobar"];
  FooBarString = [t1 customizeEnd];
  printf( "FooBarString id is: %0#8x\n", (unsigned int)FooBarString );
  [FooBarString drop];
  [aZone xprint];
  if ( _obj_debug ) exit(0);

  s1 = [String create: aZone setC: "abcdef"];
  printf( "string is: %s\n", [s1 getC] );
  [s1 setC: "foo"];
  printf( "string is: %s\n", [s1 getC] );
  [s1 catC: "bar"];
  printf( "string is: %s\n", [s1 getC] );
  [s1 drop];

  s2 = [String create: aZone];
  [s2 setC: ""];
  printf( "string is: %s\n", [s2 getC] );
  [s2 catC: "foo"];
  printf( "string is: %s\n", [s2 getC] );
  [s2 drop];

  s3 = [String create: aZone];
  printf( "string is: %s\n", [s3 getC] );
  [s3 catC: "foo"];
  printf( "string is: %s\n", [s3 getC] );
  s4 = [s3 perform: @selector( copy: ) with: aZone];
  [s4 catC: "FOO"];
  printf( "string is: %s\n", [s4 getC] );
  [s3 drop];
  [s4 drop];
  [aZone xprint];

  t1 = [String customizeBegin: aZone];
  [t1 setC: "foobar"];
  FooBarString = [t1 customizeEnd];
  printf( "FooBarString id is: %0#8x\n", (unsigned int)FooBarString );
  [FooBarString drop];
  [aZone xprint];
  if ( _obj_debug ) exit(0);

  s4 = [FooBarString create: aZone];
  printf( "string is: %s  id is: %0#8x\n", [s4 getC], (unsigned int)s4 );
  [s4 catC: "foo"];
  printf( "string is: %s\n", [s4 getC] );

  s1 = [OutputStream create: scratchZone setFileStream: _obj_xdebug];
  [s1 catC: "output string\n"];
  [s1 drop];

  s1 = [OutputStream createBegin: scratchZone];
  [s1 setFileStream: _obj_xdebug];
  s1 = [s1 createEnd];
  [s1 catC: "output string\n"];
  [s1 drop];

  [s4 xprint];
  [s4 setC: "long output string that just keeps going and going and going\n"];
  [s4 xprint];
  [s4 drop];
  [FooBarString xprint];
  [FooBarString drop];
  [aZone xprint];
  [aZone drop];
  return 0;
}