/*
* Created on Nov 30, 2006 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu
* (jactr.org) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version. This library is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jactr.core.reality.connector;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.commonreality.agents.IAgent;
import org.commonreality.time.IClock;
import org.commonreality.time.impl.BasicClock;
import org.commonreality.time.impl.OwnedClock;
import org.commonreality.time.impl.OwnedClock.OwnedAuthoritativeClock;
import org.commonreality.time.impl.WrappedClock;
import org.jactr.core.model.IModel;
/**
* local connector responsible for providing the clocks to the models, and any
* and all attachment handling for the non-existant perceptual interfaces.
*
* @author developer
*/
public class LocalConnector implements IConnector
{
/**
* logger definition
*/
static private final Log LOGGER = LogFactory
.getLog(LocalConnector.class);
static private final boolean _enableIndependentClocks = Boolean
.getBoolean("connector.independentClocks");
static private boolean _warnedAboutIndependentClocks = false;
private final OwnedClock _defaultClock;
private Map<IModel, IClock> _clocks;
private IClockConfigurator _configurator;
private boolean _useIndependentClocks = false;
/**
* default will use the system property connector.independentClocks
* effectively new
* LocalConnector(Boolean.getBoolean("connector.independentClocks"))
*/
public LocalConnector()
{
this(_enableIndependentClocks);
}
public LocalConnector(boolean useIndependentClocks)
{
if (!_warnedAboutIndependentClocks && useIndependentClocks)
{
LOGGER
.warn("Independent clocks can cause strange behavior when models interact or in systems that assume synchronized time.");
_warnedAboutIndependentClocks = true;
}
_useIndependentClocks = useIndependentClocks;
_defaultClock = new OwnedClock(0.05);
_clocks = new ConcurrentHashMap<IModel, IClock>();
setClockConfigurator(new IClockConfigurator() {
public void release(IModel model, IClock clock)
{
}
public IClock getClockFor(IModel model, IClock defaultClock)
{
if (!_useIndependentClocks)
return new WrappedClock(defaultClock);
else
return new BasicClock(true, model.getProceduralModule()
.getDefaultProductionFiringTime());
}
public IClock getClockFor(IModel model, IAgent agent)
{// this is not going to be called.
return agent.getClock();
}
});
// _defaultClock.setTime(-1);
}
/**
* @see org.jactr.core.reality.connector.IConnector#connect(org.jactr.core.model.IModel)
*/
public void connect(IModel model)
{
if (!_useIndependentClocks)
{
OwnedAuthoritativeClock auth = (OwnedAuthoritativeClock) _defaultClock
.getAuthority().get();
auth.addOwner(model);
}
IClock clock = getClockConfigurator().getClockFor(model, _defaultClock);
synchronized (this)
{
_clocks.put(model, clock);
}
}
/**
* @see org.jactr.core.reality.connector.IConnector#disconnect(org.jactr.core.model.IModel)
*/
public void disconnect(IModel model)
{
if (!_useIndependentClocks)
{
OwnedAuthoritativeClock auth = (OwnedAuthoritativeClock) _defaultClock
.getAuthority().get();
auth.removeOwner(model);
}
// _defaultClock.removeOwner(Thread.currentThread());
IClock defined = null;
synchronized (this)
{
defined = _clocks.remove(model);
}
getClockConfigurator().release(model, defined);
}
/**
* @see org.jactr.core.reality.connector.IConnector#getAgentInterface(org.jactr.core.model.IModel)
*/
public IAgent getAgent(IModel model)
{
return null;
}
/**
* @see org.jactr.core.reality.connector.IConnector#isRunning()
*/
public boolean isRunning()
{
return false;
}
public IClock getClock(IModel model)
{
// concurrent hash cant deal w/ null
if (model == null) return _defaultClock;
IClock rtn = _clocks.get(model);
if (rtn == null) rtn = _defaultClock;
return rtn;
}
/**
* @see org.jactr.core.reality.connector.IConnector#start()
*/
public void start()
{
}
/**
* @see org.jactr.core.reality.connector.IConnector#stop()
*/
public void stop()
{
}
public IClockConfigurator getClockConfigurator()
{
return _configurator;
}
public void setClockConfigurator(IClockConfigurator clockConfig)
{
_configurator = clockConfig;
}
}