/*this has the "probeDemo2b patch for "enableDestroyNotification" applied" /*mgd@swarm.org (Marcus G. Daniels) Oct. 23, 2000 DA> The agents (Swarm objects) have some internal state that can not DA> be displayed in a simple probe (for example a 2-D array or another DA> Swarm object). So I want to make a method that shows the internal DA> state. See below for an example. DA> what means "GUI_EVENT_ASYNC()" It tells the GUI to process whatever work it has queued up. For example, when you press a button that event gets queued and sits (in an internal Tk data structure) until the GUI gets told to process its queued events. GUI_EVENT_ASYNC is one way to do that. The usual way in Swarm to process queued GUI work is to call -doTkEvents, a method you get with a GUISwarm. However, in simple, self-contained examples, it is often not necessary to have a GUISwarm to make the point, so GUI_EVENT_ASYNC is a one-line way to get the same thing. DA> Is it ok to put graphs in the methods of a SwarmObject? How? Yes, there are not contextual constraints; just do it. Here's an example of creating a Canvas via a probe to visualize a 2d array of numbers. Right-click on "Controller" and then click on `createCanvas'. Finally, click on `increment'. */ #import // initSwarm #import #import // Canvas, TextItem #import // CreateDrop #include // sprintf #import // getZone #define CANVAS_HEIGHT 400 #define CANVAS_WIDTH 600 #define ROWS 5 #define COLS 10 @interface Controller: GUISwarm { int internalState[ROWS][COLS]; id canvas; id textItems[ROWS][COLS]; } - buildObjects; - (void)update; - (void)createCanvas; - (void)increment; @end @implementation Controller + create: aZone { Controller *controller = [super create: aZone]; SET_WINDOW_GEOMETRY_RECORD_NAME (controller); return controller; } - (void)update { unsigned ri, ci; for (ri = 0; ri < ROWS; ri++) for (ci = 0; ci < COLS; ci++) { id textItem; char buf[DSIZE (int) + 1]; if (textItems[ri][ci]) [textItems[ri][ci] drop]; textItem = [TextItem createBegin: getZone (self)]; [textItem setCanvas: canvas]; [textItem setX: ci * (CANVAS_WIDTH - 30) / COLS + 30 Y: 50 + ri * 80]; sprintf (buf, "%u", internalState[ri][ci]); [textItem setText: buf]; textItems[ri][ci] = [textItem createEnd]; } } - buildObjects { unsigned ri, ci; [super buildObjects]; CREATE_ARCHIVED_PROBE_DISPLAY (self); for (ri = 0; ri < ROWS; ri++) for (ci = 0; ci < COLS; ci++) { internalState[ri][ci] = (ri + 1) * (ci + 1); textItems[ri][ci] = nil; } return self; } - (void)canvasDeath { unsigned ri, ci; for (ri = 0; ri < ROWS; ri++) for (ci = 0; ci < COLS; ci++) textItems[ri][ci] = nil; [canvas drop]; } - (void)createCanvas { unsigned ri, ci; canvas = [Canvas createBegin: getZone (self)]; [canvas setWindowGeometryRecordName: "internalStateCanvas"]; canvas = [canvas createEnd]; [canvas setWidth: CANVAS_WIDTH Height: CANVAS_HEIGHT]; [canvas setWindowTitle: "internalState"]; [canvas pack]; [canvas enableDestroyNotification: self notificationMethod: M(canvasDeath)]; [self update]; } - (void)increment { unsigned ri, ci; for (ri = 0; ri < ROWS; ri++) for (ci = 0; ci < COLS; ci++) internalState[ri][ci]++; [self update]; } @end int main (int argc, const char **argv) { id controller; initSwarm (argc, argv); controller = [Controller create: globalZone]; [controller buildObjects]; [controller buildActions]; [controller activateIn: nil]; [controller go]; } /* Local Variables: compile-command: "$SWARMHOME/bin/libtool-swarm --mode=link gcc -DAPPNAME=probeDemo2 -D_GNU_SOURCE -o probeDemo2 -g -Wno-import -I$SWARMHOME/include/swarm -L$SWARMHOME/lib/swarm probeDemo2.m -lswarm -lobjc" End: */