package org.jactr.tools.masterslave.clock; /* * default logging */ 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.WrappedClock; import org.jactr.core.model.IModel; import org.jactr.core.reality.connector.IClockConfigurator; import org.jactr.core.runtime.ACTRRuntime; import org.jactr.tools.masterslave.master.MasterExtension; import org.jactr.tools.masterslave.slave.SlaveExtension; public class MasterSlaveClockConfigurator implements IClockConfigurator { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(MasterSlaveClockConfigurator.class); private IClockConfigurator _delegate; public MasterSlaveClockConfigurator(IClockConfigurator originalConfig) { _delegate = originalConfig; } /** * if the model contains the masterExtension, we will wrap its clock * * @see org.jactr.core.reality.connector.IClockConfigurator#getClockFor(org.jactr.core.model.IModel, * IAgent) */ public IClock getClockFor(IModel model, IAgent agent) { IClock masterClock = getClockForMaster(model, agent.getClock()); if (masterClock != null) return masterClock; // slave? this should never happen SlaveExtension sExt = SlaveExtension.getSlaveExtension(model); if (sExt != null) if (LOGGER.isWarnEnabled()) LOGGER .warn(String .format("Slave models do not generally have an agent provided. No clue how to handle this situation, returning agent clock")); return _delegate.getClockFor(model, agent); } /** * if the model contains the slave extension or the master extension, wrap its * clock */ public IClock getClockFor(IModel model, IClock defaultClock) { IClock masterClock = getClockForMaster(model, defaultClock); if (masterClock != null) return masterClock; masterClock = getClockForSlave(model, defaultClock); if (masterClock != null) return masterClock; return _delegate.getClockFor(model, defaultClock); } protected IClock getClockForMaster(IModel model, IClock defaultClock) { MasterExtension mExt = MasterExtension.getMaster(model); if (mExt != null) { // wrap the agent's clock with the masterslave clock // and wrap the master slave MasterSlaveClock msc = new MasterSlaveClock(defaultClock, Thread.currentThread()); WrappedClock wrapped = new WrappedClock(msc); if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Created master clock for %s", model.getName())); return wrapped; } return null; } protected IClock getClockForSlave(IModel model, IClock defaultClock) { SlaveExtension sExt = SlaveExtension.getSlaveExtension(model); if (sExt != null) { // wrap the agent's clock with the masterslave clock // and wrap the master slave MasterExtension mExt = sExt.getMaster(); WrappedClock wc = (WrappedClock) ACTRRuntime.getRuntime().getClock( mExt.getModel()); // MasterSlaveClock master = (MasterSlaveClock) wc.getMasterClock(); MasterSlaveClock master = (MasterSlaveClock) wc.getDelegate(); // master.addOwner(Thread.currentThread()); WrappedClock wrapped = new WrappedClock(master); if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Created slave clock for %s", model.getName())); return wrapped; } return _delegate.getClockFor(model, defaultClock); } public void release(IModel model, IClock clock) { /* * if the clock wrapped around a master slave clokc? */ boolean released = false; if (clock instanceof WrappedClock) { IClock master = ((WrappedClock) clock).getDelegate(); if (master instanceof MasterSlaveClock) { // msc.removeOwner(Thread.currentThread()); released = true; } } if (!released) _delegate.release(model, clock); } }