/* MGD May 11, 2000 email: swarm-support SM> when I update agentGraph4 (i.e agentGraph4 step) the function SM> "getTargetNumberOfTimesInStock " is called 4 times!!Can anybody SM> explain why? I think it should be called only twice because there SM> are only 2 sequences. That approach won't work because the parameter will not be set and reset when the EZGraph goes through plotting its sequences. Unfortunately, EZGraph doesn't provide a way to specify those parameters. If you have a fixed and small set of attributes that you want to plot, one way to deal with that is to offset into an array of selectors when you create the sequence. Another approach is break up the targets of the sequences so that different objects provide different attributes to the same selector. Using Objective C tricks its actually possible to have fake method names that convert into parameterized method invocations. Note: what follows is not a serious answer to your question, it's for the amusement of Objective C fanatics out in swarm-support land. You know who you are. ;-) */ #import #import #import #import #include // strncmp #include // sel_get_name #define BASEMETHODNAME "v" #define ATTRIBUTE_COUNT 10 @interface Agent: CreateDrop { double values[ATTRIBUTE_COUNT]; } - (double)getValueProto; - setValue: (double)value atOffset: (unsigned)valueIndex; - (double)getValue: (unsigned)valueIndex; @end @implementation Agent - setValue: (double)theValue atOffset: (unsigned)valueIndex { values[valueIndex] = theValue; return self; } - (double)getValue: (unsigned)valueIndex { return values[valueIndex]; } - (double)getValueProto { return values[0]; } - (retval_t)forward: (SEL)sel : (arglist_t)argFrame { unsigned valueIndex; const char *name = sel_get_name (sel); if (strncmp (name, BASEMETHODNAME, sizeof (BASEMETHODNAME) - 1) == 0) { if (sscanf (name, BASEMETHODNAME "%u", &valueIndex) != 1) abort (); } else abort (); { id arguments = [[[[FArguments createBegin: [self getZone]] setSelector: M(getValue:)] addUnsigned: valueIndex] createEnd]; id call = [FCall create: [self getZone] target: self selector: M(getValue:) arguments: arguments]; retval_t retValBuf = alloca (256); retval_t retVal; types_t typebuf; [call performCall]; retVal = [call getRetVal: retValBuf buf: &typebuf]; [call drop]; [arguments drop]; return retVal; } } @end @interface ObserverSwarm: GUISwarm { id schedule; id graph; id agent; } - createEnd; - buildActions; - step; - (void)stepValues: (timeval_t)t; @end @implementation ObserverSwarm - createEnd { unsigned i; const char *typeProto = sel_get_type (sel_get_any_typed_uid ("getValueProto")); [super createEnd]; graph = [EZGraph create: globalZone setTitle: "EZGraph" setAxisLabelsX: "X label" Y: "Y label" setWindowGeometryRecordName: "ezgraph"]; agent = [Agent create: self]; [self stepValues: 0]; for (i = 0; i < ATTRIBUTE_COUNT; i++) { char buf[sizeof (BASEMETHODNAME) - 1 + DSIZE (unsigned) + 1]; sprintf (buf, BASEMETHODNAME "%u", i); [graph createSequence: buf withFeedFrom: agent andSelector: sel_register_typed_name (buf, typeProto)]; } return self; } - buildActions { schedule = [[[Schedule createBegin: self] setRepeatInterval: 1] createEnd]; [schedule at: 0 createActionTo: self message: M(step)]; return self; } - (void)stepValues: (timeval_t)t { unsigned i; for (i = 0; i < ATTRIBUTE_COUNT; i++) [agent setValue: (double) ((i + 1) * t) atOffset: i]; } - step { [self stepValues: getCurrentTime ()]; [graph step]; [actionCache doTkEvents]; return self; } - activateIn: swarmContext { [super activateIn: swarmContext]; [schedule activateIn: self]; return [self getActivity]; } @end int main (int argc, const char **argv) { id observerSwarm; initSwarm (argc, argv); observerSwarm = [ObserverSwarm create: globalZone]; [observerSwarm buildObjects]; [observerSwarm buildActions]; [observerSwarm activateIn: nil]; [observerSwarm go]; return 0; } /* Local Variables: compile-command: "/opt/SDGswarm/2.1.1/bin/libtool-swarm --mode=link gcc -o ezgraph3 -Wall -Werror -g -Wno-import -I/opt/SDGswarm/2.1.1/include -L/opt/SDGswarm/2.1.1/lib ezgraph3.m -lswarm -lobjc" End: */