[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Help on walking lists of Swarm Collection
From: |
Ken Cline |
Subject: |
Re: Help on walking lists of Swarm Collection |
Date: |
Sat, 8 May 1999 15:41:03 -0400 (EDT) |
On Sat, 8 May 1999, Marcus G. Daniels wrote:
> >>>>> "WS" == William S Shu <address@hidden> writes:
>
> WS> What is not clear --
> WS> not in the manual -- is whether such changes might
> WS> adversely affect the forEach: message invoking
> WS> dropDead.
>
> If dropDead has the side effect of touching the List, the
> Index will break, and you'll probably get a segfault.
>
> Conceptually, I don't think it is clean to have agents touching global
> bookkeeping data structures. I mean, unless it is a suicide or a
> terminal illness, people don't generally cancel their utilities and
> fill out their own death certificates, etc. Instead, a death causes a
> disruption and society makes the necessary adaptations.
>
> At the code level, putting colonyList in each Agent means that there
> need to be gratuitous setColonyList: calls needed in the construction
> of each agent (or some other implicit environment like a global
> variable or global environment object).
Again, I totally agree with Marcus. You should probably
provide a funeral service in "The Almighty" (aka ModelSwarm).
Although, in a lot of cases, the agent will need to have
pointer to some global object (e.g. the ModelSwarm).
> WS> I use forEach: like so:
> WS>
> WS> {
> WS> ...
> WS> [colonyList forEach: M(dropDead)]; // destroy
> WS> [colonyList removeAll];
> WS> [colonyList drop];
> WS> colonyList = nil; // ensure no further use
> WS> ...
> WS> }
> WS>
> WS> Here, dropDead invokes methods that may remove entries
> WS> from colonyList. (In fact, each entry is supposed to
> WS> remove itself from colonyList, then destroy any pointers
> WS> to the object that holds the colonyList)
Some (*untried*) coding ideas...
Let me see, you are trying to empty the list by calling a
method (dropDead) that affects the list. You need a
collection access method that doesn't use indices, e.g.
`getFirst' or `getLast'. How about something like:
// Drop all the members of the specified colony
-(void) destroyColony: (id <Collection>) colony
{
id target = nil;
if ( [self isEmpty: colony] ) {
raiseEvent( WarningMessage, "Colony is empty!" );
return;
}
while ( [colony getCount] > 0 ) {
target = [ colony getLast ];
if ( [self isColonist: target] ) {
[ self killColonist: (id <Colonist>)target ];
} else {
raiseEvent( WarningMessage, "Target %p is NOT a" \
" colonist.", target );
// Do "traditional" member remove.
// NOTE: This assumes uniqueness of target.
[ colony remove: target ]; // <- Possible problem
[ target drop ];
}
}
// `removeAll' not needed, see `dropDead'
[ colony drop ];
}
// Kills the specified colonist
-(void) killColonist: (id <Colonist>) target {
if ( target == nil ) {
raiseEvent( WarningMessage, "Target is nil!" );
return;
}
// `dropDead' remove target from the colony and
// drops the object
[ target dropDead ];
}
// Check if the argument is null or an empty collection
-(BOOL) isEmpty: (id <Collection>) collection {
if ( collection == nil ) return TRUE;
return [ collection getCount ] <= 0;
}
// Check that the argument is non-null and adopts the
// Colonist protocol
-(BOOL) isColonist: (id) target {
if ( target == nil ) return FALSE;
return [ target conformsTo: @protocol(Colonist) ];
}
// Or, more generally...
-(BOOL) isSelfDropping: (id) target {
if ( target == nil ) return FALSE;
return [ target respondsTo: M(dropDead) ];
}
Not sure if that stuff really help...
Ken.
_________________________________________________________
Ken Cline address@hidden
SAIC VOICE (410) 571-0413
Annapolis, MD FAX (301) 261-8427
==================================
Swarm-Support is for discussion of the technical details of the day
to day usage of Swarm. For list administration needs (esp.
[un]subscribing), please send a message to <address@hidden>
with "help" in the body of the message.