/**
*
*/
package iamrescue.belief.commupdates;
import iamrescue.agent.ISimulationTimer;
import iamrescue.belief.IAMWorldModel;
import iamrescue.belief.provenance.IPropertyMerger;
import iamrescue.belief.provenance.LatestProperty;
import iamrescue.communication.ICommunicationModule;
import iamrescue.communication.messages.Message;
import iamrescue.communication.messages.MessageChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javolution.util.FastList;
import javolution.util.FastSet;
import org.apache.log4j.Logger;
import rescuecore2.config.Config;
import rescuecore2.worldmodel.EntityID;
/**
* @author Sebastian
*
*/
public class WorldModelCommsUpdater implements IWorldModelCommsUpdater {
private ICommunicationModule commsModule;
private IAMWorldModel worldModel;
private List<IMessageHandler> msgListeners;
private ISimulationTimer timer;
private IPropertyMerger propertyMerger = new LatestProperty();
private Set<MessageChannel> myTeamChannels = new FastSet<MessageChannel>();
private Config config;
private boolean hasCentreRole = false;
private EntityID myID;
// After how many time steps do we remove messages that haven't been read?
private static final int TIME_OUT = 10;
private static final Logger LOGGER = Logger
.getLogger(WorldModelCommsUpdater.class);
public WorldModelCommsUpdater(IAMWorldModel worldModel,
ICommunicationModule commsModule, ISimulationTimer timer,
Config config, EntityID myID) {
this.worldModel = worldModel;
this.config = config;
this.commsModule = commsModule;
this.msgListeners = new FastList<IMessageHandler>();
this.timer = timer;
this.myID = myID;
registerDefaultHandlers();
}
/**
*
*/
private void registerDefaultHandlers() {
addUpdateHandler(new EntityUpdateHandler(worldModel, propertyMerger));
addUpdateHandler(new EntityDeletedHandler(worldModel, propertyMerger));
addUpdateHandler(new BlockConsistencyHandler(worldModel, propertyMerger));
addUpdateHandler(new CivilianCryForHelpHandler(worldModel, config, myID));
addUpdateHandler(worldModel.getStuckMemory());
}
public void setCentreRole(List<MessageChannel> myTeamChannels) {
this.myTeamChannels.clear();
this.myTeamChannels.addAll(myTeamChannels);
hasCentreRole = true;
}
public void unsetCentreRole() {
this.myTeamChannels.clear();
this.hasCentreRole = false;
}
public List<Message> update() {
List<Message> updateMessages = new ArrayList<Message>();
int iterations = hasCentreRole ? 2 : 1;
do {
Collection<Message> messages = commsModule.getUnreadMessages();
for (Message message : messages) {
if (iterations == 2
&& !myTeamChannels.contains(message.getChannel())) {
// If two iterations and still on first iteration, ignore
// channels other than own
continue;
}
for (IMessageHandler handler : msgListeners) {
if (handler.canHandle(message)) {
if (handler.handleMessage(message)) {
if (iterations == 1 && hasCentreRole) {
// Only store updates on last iteration
updateMessages.add(message);
}
}
}
}
if (iterations == 1
&& message.getTimestepReceived() + TIME_OUT <= timer
.getTime()) {
message.markAsRead();
}
}
iterations--;
} while (iterations > 0);
// Forward all unread messages that were not from own channels
/*
* if (hasCentreRole) { Collection<Message> unreadMessages =
* commsModule.getUnreadMessages(); for (Message message :
* unreadMessages) { if (!myTeamChannels.contains(message.getChannel()))
* { updateMessages.add(message); } } }
*/
return updateMessages;
}
public void addUpdateHandler(IMessageHandler handler) {
msgListeners.add(handler);
}
}