/**
*
*/
package iamrescue.belief;
import iamrescue.belief.commupdates.IMessageHandler;
import iamrescue.communication.messages.AgentStuckMessage;
import iamrescue.communication.messages.Message;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javolution.util.FastMap;
import javolution.util.FastSet;
import rescuecore2.standard.entities.PoliceForce;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.StandardEntityURN;
import rescuecore2.standard.entities.StandardPropertyURN;
import rescuecore2.worldmodel.Entity;
import rescuecore2.worldmodel.EntityID;
import rescuecore2.worldmodel.EntityListener;
import rescuecore2.worldmodel.Property;
/**
* @author Sebastian
*
*/
public class StuckMemory implements IMessageHandler, EntityListener {
private Map<EntityID, StuckInfo> entityStuckMap = new FastMap<EntityID, StuckInfo>();
private Map<EntityID, Set<EntityID>> positionStuckMap = new FastMap<EntityID, Set<EntityID>>();
@Override
public boolean canHandle(Message message) {
return message instanceof AgentStuckMessage;
}
public void enableAutoUpdate(IAMWorldModel worldModel) {
Collection<StandardEntity> policeForces = worldModel
.getEntitiesOfType(StandardEntityURN.POLICE_FORCE);
for (StandardEntity police : policeForces) {
police.addEntityListener(this);
}
}
@Override
public boolean handleMessage(Message message) {
message.markAsRead();
AgentStuckMessage stuckMessage = (AgentStuckMessage) message;
EntityID stuck = stuckMessage.getStuckAgent();
EntityID area = stuckMessage.getArea();
int timeStep = message.getTimestepReceived();
StuckInfo stuckInfo = entityStuckMap.get(stuck);
boolean alreadyExisted = false;
if (stuckInfo != null) {
alreadyExisted = true;
if (stuckInfo.position.equals(area)) {
// No need to do anything
return false;
} else {
Set<EntityID> stuckAgents = positionStuckMap
.get(stuckInfo.position);
if (stuckAgents.size() == 1) {
positionStuckMap.remove(stuckInfo.position);
} else {
stuckAgents.remove(stuck);
}
}
}
// Add info
stuckInfo = new StuckInfo(stuck, area, timeStep);
entityStuckMap.put(stuck, stuckInfo);
Set<EntityID> alreadyStuck = positionStuckMap.get(area);
if (alreadyStuck == null) {
alreadyStuck = new FastSet<EntityID>();
positionStuckMap.put(area, alreadyStuck);
}
alreadyStuck.add(stuck);
if (alreadyExisted) {
return false;
} else {
return true;
}
}
@Override
public void propertyChanged(Entity e, Property p, Object oldValue,
Object newValue) {
if (e instanceof PoliceForce) {
if (p.isDefined()
&& p.getURN().equals(StandardPropertyURN.POSITION)) {
EntityID id = (EntityID) p.getValue();
Set<EntityID> stuck = positionStuckMap.get(id);
if (stuck != null) {
for (EntityID entityID : stuck) {
entityStuckMap.remove(entityID);
}
positionStuckMap.remove(id);
}
}
}
}
public Set<EntityID> getStuckAgents() {
return entityStuckMap.keySet();
}
public StuckInfo getStuckInfo(EntityID stuckAgentID) {
return entityStuckMap.get(stuckAgentID);
}
public static class StuckInfo {
private EntityID id;
private EntityID position;
private int timeStepFirstReceived;
public StuckInfo(EntityID id, EntityID position,
int timeStepFirstReceived) {
super();
this.id = id;
this.position = position;
this.timeStepFirstReceived = timeStepFirstReceived;
}
public EntityID getID() {
return id;
}
public EntityID getPosition() {
return position;
}
public int getTimeStepFirstReceived() {
return timeStepFirstReceived;
}
}
}