package org.jactr.modules.pm.aural.memory.impl;
/*
* default logging
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.commonreality.identifier.IIdentifier;
import org.jactr.core.buffer.BufferUtilities;
import org.jactr.core.buffer.six.IStatusBuffer;
import org.jactr.core.chunk.IChunk;
import org.jactr.core.logging.Logger;
import org.jactr.core.model.IModel;
import org.jactr.core.queue.timedevents.RunnableTimedEvent;
import org.jactr.core.runtime.ACTRRuntime;
import org.jactr.modules.pm.aural.IAuralModule;
import org.jactr.modules.pm.common.memory.IActivePerceptListener;
public class DefaultPerceptListener implements IActivePerceptListener
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(DefaultPerceptListener.class);
private IAuralModule _module;
public DefaultPerceptListener(IAuralModule module)
{
_module = module;
}
protected IChunk getNamedChunk(String name)
{
IChunk rtn = null;
try
{
rtn = _module.getModel().getDeclarativeModule().getChunk(name).get();
}
catch (Exception e)
{
LOGGER.error(String.format("Failed to get chunk %s from model", name), e);
}
return rtn;
}
public void reencoded(final IIdentifier identifier, final IChunk oldChunk,
IChunk newChunk)
{
/*
* its normal to get the reencoded event after removing the chunk from the
* buffer
*/
if (oldChunk.isEncoded()) return;
IModel model = _module.getModel();
if (model.getDeclarativeModule().willEncode(oldChunk)) return;
if (Logger.hasLoggers(model) || LOGGER.isDebugEnabled())
{
StringBuilder sb = new StringBuilder("Percept underlying ");
sb.append(oldChunk).append(" has changed too much. (").append(identifier)
.append(")");
String msg = sb.toString();
if (Logger.hasLoggers(model))
Logger.log(model, Logger.Stream.AURAL, msg);
if (LOGGER.isDebugEnabled()) LOGGER.debug(msg);
}
IChunk error = _module.getModel().getDeclarativeModule().getErrorChunk();
_module.getAuralActivationBuffer().setStateChunk(error);
_module.getAuralActivationBuffer().setErrorChunk(
getNamedChunk(IStatusBuffer.ERROR_CHANGED_TOO_MUCH_CHUNK));
_module.getAuralActivationBuffer().setExecutionChunk(error);
}
public void removed(final IIdentifier identifier, final IChunk chunk)
{
/*
* and set error. we do this on the model thread just in case there are
* buffer changes currently going on..
*/
if (chunk.isEncoded())
{
if (LOGGER.isDebugEnabled())
LOGGER
.debug(String
.format(
"%s is no longer audible, but chunk has been encoded. Ignoring message.",
identifier));
return;
}
/*
* log
*/
IModel model = _module.getModel();
if (model.getDeclarativeModule().willEncode(chunk))
{
if (LOGGER.isDebugEnabled())
LOGGER
.debug(String
.format(
"%s is no longer audible, but chunk is about to be encoded. Ignoring message.",
identifier));
return;
}
if (Logger.hasLoggers(model) || LOGGER.isDebugEnabled())
{
StringBuilder sb = new StringBuilder("Percept underlying ");
sb.append(chunk).append(" is no longer audible. (").append(identifier)
.append(")");
String msg = sb.toString();
if (Logger.hasLoggers(model))
Logger.log(model, Logger.Stream.AURAL, msg);
if (LOGGER.isDebugEnabled()) LOGGER.debug(msg);
}
/**
* only set the error if the chunk is currently in the buffer. If not, it's
* up to the activation buffer itself..
*/
if (chunk.hasBeenDisposed()
|| BufferUtilities.getContainingBuffers(chunk, true).contains(
_module.getAuralActivationBuffer()))
{
IChunk error = _module.getModel().getDeclarativeModule().getErrorChunk();
_module.getAuralActivationBuffer().setStateChunk(error);
_module.getAuralActivationBuffer().setErrorChunk(
getNamedChunk(IStatusBuffer.ERROR_NO_LONGER_AVAILABLE_CHUNK));
_module.getAuralActivationBuffer().setExecutionChunk(error);
}
}
public void updated(IIdentifier identifier, IChunk chunk)
{
/*
* if the chunk is no longer visible, pretend it was removed..
*/
if (_module.getAuralMemory().getIndexManager().getIndexChunk(chunk) == null)
{
removed(identifier, chunk);
return;
}
/*
* first log that the chunk has changed.
*/
IModel model = _module.getModel();
if (Logger.hasLoggers(model) || LOGGER.isDebugEnabled())
{
StringBuilder sb = new StringBuilder("Percept underlying ");
sb.append(chunk).append(" has changed. (").append(identifier).append(")");
String msg = sb.toString();
if (Logger.hasLoggers(model))
Logger.log(model, Logger.Stream.AURAL, msg);
if (LOGGER.isDebugEnabled()) LOGGER.debug(msg);
}
double start = ACTRRuntime.getRuntime().getClock(model).getTime();
/*
* now we need to set the buffer as busy for 50ms
*/
double end = start + 0.05;
model.getTimedEventQueue().enqueue(
new RunnableTimedEvent(start, new Runnable() {
public void run()
{
_module.getAuralActivationBuffer().setExecutionChunk(
_module.getModel().getDeclarativeModule().getBusyChunk());
}
}));
model.getTimedEventQueue().enqueue(
new RunnableTimedEvent(end, new Runnable() {
public void run()
{
_module.getAuralActivationBuffer().setExecutionChunk(
_module.getModel().getDeclarativeModule().getFreeChunk());
}
}));
}
public void newPercept(IIdentifier identifier, IChunk chunk)
{
/*
* flag the percept as new..
*/
// removed into anonymous inner in default visual module
// so that it can be accessed immediately after the chunk is available
// IFINSTFeatureMap finstMap =
// _module.getVisualMemory().getFINSTFeatureMap();
// if (finstMap != null && !finstMap.isAttended(identifier))
// finstMap.flagAsNew(identifier, chunk, _module.getVisualMemory()
// .getOnsetDuration());
}
}