The objectbase library contains the most basic objects users need to design their agents and swarms. It also serves, at present, as a repository for the probe machinery, which is provided for every SwarmObject. The way the classes in this library are to be used is varied. But, basically, it is provided so that the user will have something to subclass from for her own objects and Swarms.
The best way to explain how the library should be used is to walk through an example. So, using Heatbugs, we'll walk through the ways objectbase is used and discuss them. Since more documentation is usually better than less, I'm going to explain things at a low level so that those not familiar with Objective C will understand the discussion. If you already are familiar with Objective C, then you should skip this part.
First off, the basic elements of the Heatbugs simulation are the heatbugs, the model swarm (which bundles the heatbugs), and the observer swarm (which bundles the displays of the probes poking into the model swarm and the heatbugs). The interface files for each show what must be imported and the declaration syntax needed to subclass from SwarmObject.
We'll use Heatbug.h for our discussion
        here.  The first part of the file shows the C-preprocessor
        imports needed:
#import objectbase/SwarmObject.h #import space.h #import "HeatSpace.h" #import tkobjc/Raster.h
The #import objectbase/SwarmObject.h;
          is included in order to subclass from
          SwarmObject.  However, to provide
          backwards compatibility, we've placed this import in the
          library interface file objectbase.h as
          well, which means one could subclass from
          SwarmObject by simply importing the
          objectbase.h file.  This is discouraged
          in order to make the library interfaces as standard as
          possible.
      
The next objectbase relevant piece of code in this file is:
@interface Heatbug: SwarmObject
{
  double unhappiness;		
  int x, y;			
  HeatValue idealTemperature;	
  HeatValue outputHeat;		
  float randomMoveProbability;	
  				
  Grid2d * world;		
  int worldXSize, worldYSize;	
  HeatSpace * heat;		
  Color bugColor;		
}
The @interface keyword indicates that
        you are beginning the definition of the part of an object (a
        Heatbug in this case) that will be
        visible to other objects.  The Heatbug:
        SwarmObject indicates that you are calling this
        object Heatbug and it is a subclass of
        SwarmObject.  What follows between the
        curly braces ({}) are the instance variables defined for the
        Heatbug class above and
        beyond those inherited from the
        SwarmObject class.
      
Inside this "agent," we have defined several parameters associated with either the agent, itself, or the space in which it sits. Any data that will need to be present throughout all the behavior and lifetime of the agent should be declared here. Also, anything declared here will be accessible to the probe machinery, and so will be capable of being manipulated and viewed from outside the agent.
Next come the message prototypes to which this agent will
        respond.  And it is worth noting again that these are
        in addition to those declared in the
        SwarmObject superclass.  So, not only
        will other objects be able to send messages to this agent that
        are declared here, but other objects will be able to send all
        the messages declared in the
        objectbase/SwarmObject.h imported
        previously.  The messages prototyped here will dictate what
        the compiler thinks this object can respond to.  Hence, if any
        part of any of these prototypes differs from the corresponding
        function definition in the Heatbug.m file,
        then the compiler will say something like Object:
        aHeatbug does not respond to xyz, where "xyz" is the
        name of the message that is being sent to the
        Heatbug.  A script is provided with the
        Swarm distribution that fixes header file prototypes to match
        the message declarations in the corresponding ".m" file.  This
        script should be in the $SWARMHOME/bin
        directory and is called m2h.
      
One more thing to notice about these prototypes is that
        some of them are duplicates of what appears in the
        objectbase/SwarmObject.h file.  This means
        that when the message is called on a
        Heatbug object, it will execute the
        method defined here and not the one in the
        SwarmObject class.  In the
        objectbase library, the following
        messages are intended to be overridden, as necessry:
        create:, createBegin:, createEnd, customizeBegin:,
        customizeEnd, customizeCopy:, describe:, and
        getInstanceName. Each of these messages do specific
        things that may change from subclass to subclass of
        SwarmObject.  In this case, however,
        we're only overriding createEnd.  The
        differences between we implement it in
        Heatbugs and the default is not that
        significant.  But, it should be pointed out that when
        overriding certain messages, like
        createBegin: and
        createEnd, the new method should call the
        superclass' version of the message, as well.  This is done
        using the default pointer to the superclass, designated
        super.  The syntax in the
        Heatbugs case is:
[super createEnd];
The reasons for doing this are related to the object phase protocols used by defobj. If you would like more info on that, see the .
Finally, the @end keyword signifies the
        end of the interface definition.  GNU Objective C allows one
        to leave this off; but, it is not good practice.
And that's it. Of course, there're a few tricky aspects to using the objectbase library that weren't mentioned here. Some of them will be mentioned in the Advanced Usage Notes and the Implementation Notes; but, the best way to learn is to examine the way the demo applications do it and try to make some changes yourself.
Subclassing from the Swarm class works very similar to subclassing from SwarmObject.
The ActivityControl object provides much more finely grained control over the execution of an interactive simulation. It addresses both the problems of not being able to stop the simulation at any given point in any given activity and provides an initial step towards a Swarm debugger.
An activity controller can be attached to
        any activity that is created in a Swarm
        simulation, including those that are created for use only by
        the Swarm kernel.  The controller then provides the basic
        activity manipulation messages on that activity, which are:
        run, stop, next, step, stepUntil, and
        terminate.
      
The presence of the ActivityControl
        object might cause some confusion about what role the
        ControlPanel should play in the
        controlled execution of the various schedules.  The
        ControlPanel should still be used for the
        top-level control of any simulation that is running in a
        context where random interference is expected
        (like under a GUISwarm where the user may click a button at
        any time).  The reason this is true is because the
        ControlPanel sends pseudo-interrupts to
        the infinite loop we use to perpetuate execution of the top
        level Swarm (which can only be seen in the form of the
        go message on a
        GUISwarm at present).  This type
        of control may change in the future! But, for now, it
        is how we monitor the control state of the simulation.
      
Now, having said that, the
        ControlPanel should no longer be used to
        run the simulation.  It should only be used to instantiate the
        control context and quit the entire simulation.  That means
        that sometime in the future, the Go and the
        Stop buttons will be removed from the
        ControlPanel display.  They have been
        left in for backwards compatibility so that applications that
        do not use the new ActivityControl will
        retain their (albeit handicapped) controllability.  Also, the
        current Time Step button will be renamed to
        Start to be consistent with it's new
        purpose.
      
In order to use the new control mechanism, you must place code like the following in the top-level Swarm. (This code was taken from a modified mousetrap demo app.)
observerActCont = [ActivityControl createBegin: [self getZone]]; observerActCont = [observerActCont createEnd]; [observerActCont attachToActivity: [self getSwarmActivity]]; [probeDisplayManager createProbeDisplayFor: observerActCont];
This creates an ActivityControl and
        attaches it to the top-level activity (in this case an
        observerSwarm).  It also creates a display
        for the controller. (The probe map for the
        ActivityControl class is designed within
        the ActivityControl, itself.  This is
        done because all of these objects are expected to look the
        same to any outside object.)  With this activity controller,
        you will then be able to run, stop, next, step,
        stepUntil, and terminate that
        activity.
      
There are some tricky aspects to successfully using an ActivityControl object that the Advanced Usage Notes will cover.