package org.jactr.modules.pm.common.memory.impl;
/*
* default logging
*/
import java.util.Collection;
import java.util.concurrent.Executor;
import javolution.util.FastList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.commonreality.agents.IAgent;
import org.commonreality.object.IAfferentObject;
import org.jactr.core.model.IModel;
import org.jactr.core.queue.timedevents.RunnableTimedEvent;
import org.jactr.modules.pm.common.afferent.DefaultAfferentObjectListener;
/**
* object listener that can delay the removal of percepts..
*
* @author harrison
*/
public class DelayableAfferentObjectListener extends
DefaultAfferentObjectListener
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(DelayableAfferentObjectListener.class);
private double _perceptualDelay = 0;
private final IModel _model;
public DelayableAfferentObjectListener(IModel model, IAgent agent,
Executor executor)
{
super(agent, executor);
_model = model;
}
protected IModel getModel()
{
return _model;
}
public double getPerceptualDelay()
{
return _perceptualDelay;
}
public void setPerceptualDelay(double delay)
{
_perceptualDelay = delay;
}
/**
* if no delay, process immediately. If delay, post a timed event that will
* trigger processing later..
*
* @param toBeRemoved
* @see org.jactr.modules.pm.common.afferent.DefaultAfferentObjectListener#objectsRemoved(java.util.Collection)
*/
protected void objectsRemoved(Collection<IAfferentObject> toBeRemoved)
{
if (_perceptualDelay <= 0)
super.objectsRemoved(toBeRemoved);
else
delayRemoval(toBeRemoved);
}
protected void delayRemoval(Collection<IAfferentObject> toBeRemoved)
{
// copy of the collection as it will be recycled
final FastList<IAfferentObject> internalToBeRemoved = FastList
.newInstance();
internalToBeRemoved.addAll(toBeRemoved);
double currentTime = getAgent().getClock().getTime();
/*
* run on the CR executor, this does the actual work..
*/
final Runnable removalProcessor = new Runnable() {
public void run()
{
for (IAfferentObject object : internalToBeRemoved)
objectRemoved(object);
FastList.recycle(internalToBeRemoved);
}
};
/*
* the timedevent queues up the actual processing so that it is still
* performed on the CR executor.
*/
RunnableTimedEvent trigger = new RunnableTimedEvent(currentTime
+ getPerceptualDelay(), new Runnable() {
public void run()
{
/*
* now we can queue up the processing to actually do the work
*/
getExecutor().execute(removalProcessor);
}
});
getModel().getTimedEventQueue().enqueue(trigger);
}
}