MultiGrid2d class documentation

Authors

Generated by pauljohn

Software documentation for the MultiGrid2d class

MultiGrid2d : SwarmObject

Declared in:
MultiGrid2d.h
Conforms to:
GridData

This code is made available under the GPL (GNU general public license) with the additional proviso that any users notify the author of their use and share their code with the original author. A copy of version 2 of the GPL is included in this directory, but you can use a newer GPL at your choice. The author assumes no liability for any inconvenience or damage caused by this software and offers no warranty of any kind. Class MultiGrid2d.h, Paul Johnson, descended from Class "MoGrid2d" by Sven Thommesen which had been modified by Pietro Terna Introduction. This replacement for Grid2d allows for Multiple Occupancy! Each occupied position has a "cell" object, and that cell holds objects a collection. MultiGrid2d is not a sublclass of Grid2d, it is a free standing combination space/container class. It is free standing and separate from Grid2d partly to assure that no IVARS or methods are unintentinally inherited in this multi-agent-per-cell environment. To assure that MultiGrid2d can act as a data provider by Swarm, it adopts the GridData protocol of Swarm, which means that it is fully qualified to act as a discrete2dToDisplay for Raster displays. By default, the cell uses an ordinary Swarm list as the collection, but the user can provide for a new kind of container. Why this feature? Some collections are faster for extracting particular objects by name, while others are faster for finding an object at a particular offset, while others are faster for finding the oldest, biggest, fattest, and so forth. If your objects are fixed at particular positions, a cell that is based on a Swarm Array would work great. So I generalize to allow any kind of collection the user desires. I also allow user-defined methods to be accessed for any particular position in the grid. How is this done? Think of each "thing" in the grid as a cell, which can accept and give back items, and it can also carry out other actions you want. The "default" cell class is MultiGridCell, which uses a swarm list class as a container. The user can create a subclass of MultiGridCell, or can create a class from scratch, as long as it adopts the protocol AppCell, which is defined in MultiGridCell.h. This protocol requires that the cell container be able to add, remove, and find objects, and also to pass through messages to them. My AppCell (documented in) uses Swarm collection style names for methods. All of this seems pretty obvious to me, but only because i've been looking at this for 3 years. When the grid is created, the user must tell the grid what "cell Class" to use. If none is specified before createEnd is called, then the MultiGridCell is assumed. (The setCellClass: method sets the cell class for the grid.) The Cell object has a list instance variable. That's the collection. It may also have other instance variables and it can be used for any data-gathering purpose, including display purposes (create drawSelfOn method and so forth). Objects/agents are added to or removed from such lists, rather than from the underlying grid. Cells are created as needed, dynamically, when agents are added at a point. (The grid is created initially with no Cell objects.) This version uses a recycler to grab MultiCells that are no longer in use. They are initialized and reused. This behavior saves on memory and it may even make a model faster if cells need not be constantly recreated. It depends on whether your grid is sparsely populated, I think. You can turn off the automatic removal of empty cells with a CPP flag, NO_AGGRESSIVE_RECYCLING. This leaves the cells, so they eagerly await a chance to insert an object for you. I have many methods in here with names that start with "passThrough". These methods take a selector argument (and possibly another argument). The idea here is that if one wants each cell object to carry out a certain method, then the pass through object can pass through that selector's method to all cells (see passThroughToAllCells:). Or, in the case of passThroughToAllObjects, it causes each object in the grid to be sent a message. Or, in the cases of passThroughToCell:atX:Y:, or passThroughToObjects:atX:Y:, a message is passed to a particular cell or to all objects in that cell. If you have ever looked at the Objective-C root class Object, you will have seen the "perform: (SEL) aSelector" method, and I use that same idea in these pass through methods. Because of these "passThrough" methods, users who create a custom cell class have to be a little careful to implement or at least create stubs for methods like "performForEach". Or subclass from MultiGridCell. Since MultiGridCell implements these, I believe that any subclass that uses a Swarm compliant collection will be acceptable and these methods need not be overridden. There is a special passThrough method, though, which I would point out: - passThroughToCellCreation: (SEL) aSelector{This sets the values of features that might be needed when cells are created inside the grid. If your Cell class requires some customization, say a Cell object needs to have a variable set or something like that, then this passThrough makes sure the Grid knows what it is supposed to do. It works so that every time the Grid creates a cell, it performs this method, i.e., [cell perform: aSelector]; I have found some cases where there is no other way to get the desired functionality of the Cell and still work with a general purpose grid like MultiGrid2d. Here is an example of a sequence of commands that create a MultiGrid2d with a user-customized cell class called "AppSpecificCell". homeGrid = [MultiGrid2d create: self setSizeX: worldXSize Y: worldYSize Cells: [AppSpecificCell class]];
[homeGrid passThroughToCellCreation: M(setRasterList:) with: [observerSwarm getRasterList: nhood]]; The grid is created, told to use cells of class AppSpecificCell, and every time a cell is created, it is told to setRasterList: with a given input variable. So that whenever it spawns a new cell, it passes on a particular message to that cell. Sometimes I have found it handy to have a "global_list" of all objects that have ever been inserted. In MultiGrid2d.hm, one can see CPP flags that turn on the creation of a global object list and maintenance of it when items are inserted and removed. This version uses an AVL Tree to keep track of objects so that removal of specific objects is fast. This big list can be used to tell all objects in the grid to do something, or to get a count of all objects in the grid. Of course, you need my AVLSet class to make that work, but it is included in this tarball. The CPP flag for that is KEEP_GLOBAL_LIST I'm also providing an example of a cell subclass that I use in an application. The original MoGrid2d was authored by Sven Thommesen (c) Sven Thommesen 1997 (sthomme@humsci.auburn.edu). Sven's grid held Swarm lists. It had some functionality to copy and shuffle lists that I don't maintain here. If you need to shuffle a list, get the collection and shuffle it yourself. Sven is not responsible for any errors in this new (significantly revised and generalized) multiple occupancy grid. My earlier effort WrappedListGrid2d was not so generally functional as this one.


Instance Variables

Method summary

create: setSizeX: Y: 

+ (id) create: (id)aZone setSizeX: (unsigned)x Y: (unsigned)y;
This is a designated initialiser for the class.

Create a MultiGrid2d that is x wide and y high


create: setSizeX: Y: Cells: 

+ (id) create: (id)aZone setSizeX: (unsigned)x Y: (unsigned)y Cells: (Class)aClass;
This is a designated initialiser for the class.

Creates a MultiGrid2d that is x wide, y high, and uses the indicated class type for the cells


_I_Using 

- (id) _I_Using;

Warning the underscore at the start of the name of this method indicates that it is private, for internal use only, and you should not use the method in your code.


add: atX: Y: 

- (id) add: (id)anObject atX: (unsigned)x Y: (unsigned)y;

Adds an object into the cell at x,y


allocLattice 

- (id*) allocLattice;

Copied from Swarm's Grid2d


createCellX: Y: 

- (id) createCellX: (unsigned)x Y: (unsigned)y;

In order to put items at x,y, a cell must exist there. This creates the cell.


createEnd 

- (id) createEnd;

Finalize creation of the object


deleteAllAtX: Y: 

- (void) deleteAllAtX: (unsigned)x Y: (unsigned)y;

Remove and destroy (drop!) all objects in the cell's collection at x,y.


deleteObject: atX: Y: 

- (id) deleteObject: (id)anObject atX: (unsigned)x Y: (unsigned)y;

Search through the cell's collection for the desired object. If it is found, delete it from the collection and return it. Otherwise return nil;


getCellAtX: Y: 

- (id) getCellAtX: (unsigned)x Y: (unsigned)y;

Returns a pointer to the cell object at ( x,y)


getCollectionAtX: Y: 

- (id) getCollectionAtX: (unsigned)x Y: (unsigned)y;

Return the collection in the cell at x,y


getFirstAtX: Y: 

- (id) getFirstAtX: (unsigned)x Y: (unsigned)y;

Ask the cell's collection for its first member and returns a pointer to it


getGlobalList 

- (AVLSet*) getGlobalList;

Return a set full list of all objects throughout the grid. I don't really recommend this unless you compile with KEEP_GLOBAL_LIST. If no globalList has been kept, then this method will cause a cycling across all cells in the grid to collect up references to their members. That's slow.


getLastAtX: Y: 

- (id) getLastAtX: (unsigned)x Y: (unsigned)y;

Ask the cell's collection for its last member and returns a pointer to it.


getLattice 

- (id*) getLattice;

Returns the underlying lattice that is used to organize data inside this grid. Only people who really understand the way Grid2d works should ever consider using this method.


getObjectAtX: Y: 

- (id) getObjectAtX: (unsigned)x Y: (unsigned)y;

This is the same as "[getCell:atX:Y:]". It is included here because we need to make sure that the getObjectAtX:Y: method from Grid2d is not called. That would obliterate the cell's collection and replace it with the single object.


getOffsets 

- (long*) getOffsets;

Returns the offsets method that is used to "index into" the lattice.Only people who really understand the way Grid2d works should ever consider using this method.


getSizeX 

- (unsigned) getSizeX;

Returns the integer width of the grid


getSizeY 

- (unsigned) getSizeY;

Returns the integer height of the grid


getValueAtX: Y: 

- (long) getValueAtX: (unsigned)x Y: (unsigned)y;

Asks the cell for its "value" and returns it. The value returned depends on your implementation of the cell class.


makeOffsets 

- (id) makeOffsets;

Copied from Swarm's Grid2d


makeProbeAtX: Y: 

- (id) makeProbeAtX: (unsigned)x Y: (unsigned)y;

Creates a Swarm probe on the cell at x,y


numberOfObjectsAtX: Y: 

- (unsigned) numberOfObjectsAtX: (unsigned)x Y: (unsigned)y;

Return the number of items in the collection in cell x,y


passThroughToAllCells: 

- (id) passThroughToAllCells: (SEL)aSelector;

In case one wants all cells that exist in a MultiGrid2d to carry out some method, this is the way to get it done.


passThroughToAllCells: with: 

- (id) passThroughToAllCells: (SEL)aSelector with: (id)arg1;

In case one wants all cells that exist in a MultiGrid2d to carry out some method, this is the way to get it done. This method allows a selector to be passed through along with one argument.


passThroughToCell: atX: Y: 

- (id) passThroughToCell: (SEL)aSelector atX: (unsigned)x Y: (unsigned)y;

In case one wants a particular cells that exist in a MultiGrid2d to carry out some method, this is the way to get it done.


passThroughToCell: with: atX: Y: 

- (id) passThroughToCell: (SEL)aSelector with: (id)arg1 atX: (unsigned)x Y: (unsigned)y;

In case one wants a particular cells that exist in a MultiGrid2d to carry out some method, this is the way to get it done. This method allows a selector to be passed through along with one argument.


passThroughToCellCreation: 

- (id) passThroughToCellCreation: (SEL)aSelector;

When a cell is created, and you want it to run some method to initialize itself, use this to "pass through" that initializing method to the cell.


passThroughToCellCreation: with: 

- (id) passThroughToCellCreation: (SEL)aSelector with: (id)arg1;

When a cell is created, and you want it to run some method to initialize itself, use this to "pass through" that initializing method to the cell. This method allows the user to add one standard argument that is passed on to all cells.


passThroughToObjects: 

- (id) passThroughToObjects: (SEL)aSelector;

In the case that one wants all of the objects that inhabit a MultiGrid2d to do something, this is the way to get it done. This will cause the MultiGrid2d to have each object in each cell execute the given selector.


passThroughToObjects: atX: Y: 

- (id) passThroughToObjects: (SEL)aSelector atX: (unsigned)x Y: (unsigned)y;

In the case that one wants all of the objects that inhabit a particular cell in the MultiGrid2d to do something, this is the way to get it done. This will cause the MultiGrid2d to have each object in the cell execute the given selector


passThroughToObjects: with: 

- (id) passThroughToObjects: (SEL)aSelector with: (id)arg1;

In the case that one wants all of the objects that inhabit a MultiGrid2d to do something, this is the way to get it done. This will cause the MultiGrid2d to have each object in each cell execute the given selector. This allows one argument to be passed along with the selector to each object.


passThroughToObjects: with: atX: Y: 

- (id) passThroughToObjects: (SEL)aSelector with: (id)arg1 atX: (unsigned)x Y: (unsigned)y;

In the case that one wants all of the objects that inhabit a particular cell in the MultiGrid2d to do something, this is the way to get it done. This will cause the MultiGrid2d to have each object in the cell execute the given selector. This allows one argument to be passed along with the selector to each object.


putObject: atX: Y: 

- (id) putObject: (id)anObject atX: (unsigned)x Y: (unsigned)y;

This is the same as "[add:atX:Y:]". It is included here because we need to make sure that the putObject method from Grid2d is not called. That would obliterate the cell's collection and replace it with the single object.


removeAllAtX: Y: 

- (void) removeAllAtX: (unsigned)x Y: (unsigned)y;

Remove all objects in the cell's collection at x,y. This does not destroy objects, it just removes references to them. So if other references to these objects exist, then they can still be used.


removeFirstAtX: Y: 

- (id) removeFirstAtX: (unsigned)x Y: (unsigned)y;

Tell the cell's collection to remove its first element and return it to the caller


removeLastAtX: Y: 

- (id) removeLastAtX: (unsigned)x Y: (unsigned)y;

Tell the cell's collection to remove its first element and return it to the caller


selectRandomMemberX: Y: 

- (id) selectRandomMemberX: (unsigned)x Y: (unsigned)y;

Note: this does not delete or remove the randomly chosen member. it simply gives back a pointer to it. Similar to getFirst or getLast in that respect.


setCellClass: 

- (void) setCellClass: (Class)aClass;

Sets the Class that will be used to create the Cells in the Grid. Should be a subclass or replacement for MultiGridCell. If you don't specify a class here, it assumes you want ordinary Swarm lists as your containers in the cells. If you custom-design a cell class which has containers and implements the protocol "AppCell", then use your cell instead.


setSizeX: Y: 

- (id) setSizeX: (unsigned)x Y: (unsigned)y;

The size of the grid is x wide and y high




Instance Variables for MultiGrid2d Class

cellArgument

@protected id cellArgument;

Description forthcoming.


cellClass

@protected Class cellClass;

Description forthcoming.


cellSelector1

@protected SEL cellSelector1;

Description forthcoming.


globalList

@protected AVLSet* globalList;

Description forthcoming.


lattice

@protected id* lattice;

Description forthcoming.


offsets

@protected long int* offsets;

Description forthcoming.


recyclerList

@protected id recyclerList;

Description forthcoming.


xsize

@protected unsigned int xsize;

Description forthcoming.