One of the most troublesome exercises in computer programming is the management of dynamically allocated memory. The correct usage of dynamic memory requires a great deal of care, and when a portion of memory is no longer needed, is must be "freed," made available to the central processor. If memory is allocated and then forgotten, a "memory leak" is said to exist because the program does not tell the operating system to reclaim unused memory addresses.
The Swarm libraries are designed to handle memory allocation with a minimum of user intervention. The createBegin and create commands allocate memory and the user is not expected to think about where the RAM comes from to store an object. Similarly, when a program is finished with an object, that object can be sent the drop message and that should take care of freeing the memory that the object used.
The create statements used in Swarm typically have this flavor:
someUserCreatedObject = [SomeSwarmLibraryObject create: someMemoryZoneHere];
(The method create can be replaced by a createBegin/createEnd pair as described above.) More specific examples are discussed below and are of course scattered throughout the Swarm examples. The important thing is that an object in the Swarm library is able to respond to a method that creates an instance of itself and that instance lives in a memory zone that is managed by the Swarm library.
In the main.m file, the top level Swarm is created and it is allocated into an instance of Zone called globalZone.
theTopLevelSwarm = [HeatbugObserverSwarm createBegin: globalZone];
This globalZone is created when the initSwarm function is called at the beginning of a swarm program. The top level Swarm is told to create itself in that space. Any Swarm objects of type Swarm or GUISwarm are able to serve as memory zones. Inside the ModelSwarm one sees a command such as:
probeMap = [EmptyProbeMap createBegin: self];
This tells the EmptyProbeMap class in the Swarm library to create an instance of itself in the memory zone allocated by the ModelSwarm, and that allocated object is to be named probeMap.
The objects at the top level of the swarm hierarchy (whether Swarm or GUISwarm) have the power to "create space" for objects that live inside them. As the code in main.m proceeds through the creation of theTopLevelSwarm, it is allocating memory and setting other important creation-state variables. Then, that newly created object is told to go through its paces:
[theTopLevelSwarm buildObjects]; [theTopLevelSwarm buildActions]; [theTopLevelSwarm activateIn: nil]; [theTopLevelSwarm go];
When you go look at the buildObjects method executed by the theTopLevelSwarm, what do you find? Depending on what edition of the Heatbugs source you have, you will find something like this:
heatbugModelSwarm = [HeatbugModelSwarm create: self];
In this code, the self is the observer level, meaning that the HeatbugModelSwarm class is told to create an instance of itself in the memory zone provided by the observer, and that allocated object is named heatbugModelSwarm.
If you then follow the code into the HeatbugModelSwarm.m file, you find it has createBegin commands that initialize a number of instance variables and objects. Unless you have a pretty old piece of code, those objects will be created in the memory zone self, the space provided by the model swarm itself.
Objects that are of type SwarmObject are not memory zones, and so when objects are created inside classes that inherit from SwarmObject, a command to allocate memory must be used.
bugPixmap = [Pixmap createBegin: [self getZone]];
The bugPixmap object is created inside Heatbug.m, but the name of the memory zone where that object "lives" has to be retrieved with the [self getZone] command. The [self getZone] method returns the name of the zone in which the bug exists, which in this case is heatbugModelSwarm.