import java.lang.reflect.Type; import java.util.Comparator; import java.util.Iterator; /** * This class lets you take a class which derives from IAgent and wrap * it as a TreeAlgAgent, so you can use it with the tree-based * connectivity maintenance algorithm. * It automatically makes the "parent preference relation" into * "prefer nodes which are closer to you". * @author mds * * @param This is the type of the agent it wraps. I think * everything should be okay if you don't supply it (thus making it default to * IAgent), but if you need to access class-specific member functions for whatever * agent you pass, the TAgent class helps alleviate unneccessary casting. */ public class TreeAlgAgentAdapter implements ITreeAlgAgent { TAgent m_agent; public TreeAlgAgentAdapter(TAgent agentToWrap) { m_agent = agentToWrap; } public TAgent accessAgent() { return m_agent; } public TreeAlgAgentAdapter(TreeAlgAgentAdapter src) { m_agent = (TAgent)(src.m_agent.makeCopy()); } public IMsg getMsgAnnotation(ILogicVarBundle vars, double [] arrLfState, int nIdx) { return new AgentMsgHelpers.PosMsg(arrLfState, nIdx*2, 2); } public java.lang.reflect.Type getAnnoteType() { return AgentMsgHelpers.PosMsg.class; } class lclCompare implements java.util.Comparator { TreeConstraintState m_agentSorting; AgentMsgHelpers.PosMsg m_posMsg; public lclCompare(TreeConstraintState agentSorting) { m_agentSorting = agentSorting; m_posMsg = (AgentMsgHelpers.PosMsg) (m_agentSorting.getMsgAddition(AgentMsgHelpers.PosMsg.class)); } /** * smaller number means more preference. */ public int compare(TreeConstraintState treeState1, TreeConstraintState treeState2) { IMsg attach1 = treeState1.getMsgAddition(AgentMsgHelpers.PosMsg.class); IMsg attach2 = treeState2.getMsgAddition(AgentMsgHelpers.PosMsg.class); // prefer to attach to things other than yourself if(treeState1.getId() == m_agentSorting.getId() && treeState2.getId() != m_agentSorting.getId()) { return 1; } else if(treeState2.getId() == m_agentSorting.getId() && treeState1.getId() != m_agentSorting.getId()) { return -1; } if(treeState1.getRootId() >= 0 && treeState1.getRootId() < treeState2.getRootId()) { return -1; } if(treeState2.getRootId() >= 0 && treeState2.getRootId() < treeState1.getRootId()) { return 1; } try { AgentMsgHelpers.PosMsg pos1 = (AgentMsgHelpers.PosMsg) attach1; AgentMsgHelpers.PosMsg pos2 = (AgentMsgHelpers.PosMsg) attach2; double lfDist1Sqrd = m_posMsg.getDistSqrd(pos1); double lfDist2Sqrd = m_posMsg.getDistSqrd(pos2); if(lfDist1Sqrd < lfDist2Sqrd) { return -1; } if(lfDist1Sqrd > lfDist2Sqrd) { return 1; } } catch(Exception e) { } if(treeState1.getId() == m_agentSorting.getParentId() && treeState2.getId() != m_agentSorting.getParentId()) { return -1; } if(treeState2.getId() == m_agentSorting.getParentId() && treeState1.getId() != m_agentSorting.getParentId()) { return 1; } return 0; // equality if all else fails } } /** * gets a comparator for sorting ITreeAlgAgent nodes by preference * @return Comparator -- smaller number means more preference */ public java.util.Comparator getPrefComp(TreeConstraintState agentSorting) { return new lclCompare(agentSorting); } public ITreeAlgAgent makeCopy() { // TODO Auto-generated method stub return new TreeAlgAgentAdapter(this); } public boolean checkStateValidity(StateBundle state) { return m_agent.checkStateValidity(state); } public void getMsgs(ILogicVarBundle discreteState, IDiscreteDynamicsCallback dynCallback, double[] arrLfStateCont, double lfCurrTime, int nIdxStateOffset, Iterator channelsToSendOn) { m_agent.getMsgs(discreteState, dynCallback, arrLfStateCont, lfCurrTime, nIdxStateOffset, channelsToSendOn); } public StateBundle updateState(ILogicVarBundle statePrev, double[] arrLfStateCont, double lfCurrTime, int nIdxStateOffset, IEnvironment env, Iterator channelsRecieveFrom) { return m_agent.updateState(statePrev, arrLfStateCont, lfCurrTime, nIdxStateOffset, env, channelsRecieveFrom); } }