import java.util.Iterator; import java.util.Collection; import java.util.Vector; /** *

* Set of (static) helper routines to make writing agents easier. *

* @author Michael Schuresko * @version %I%, %G% * @since 1.1 */ public class AgentMsgHelpers { public AgentMsgHelpers() { } /** * * @param toDup iterator of communication links to duplicate * @return vector containing two copies of the iterator to * communication links. */ public static Vector > duplicateLinks(Iterator toDup) { return nDuplicateLinks(toDup, 2); // Vector > result = new Vector< Iterator >(2); // Vector vec1 = new Vector (); // Vector vec2 = new Vector (); // while(toDup.hasNext()) { // CommLink nextLink = toDup.next(); // vec1.add(nextLink); // vec2.add(nextLink); // } // result.add(vec1.iterator()); // result.add(vec2.iterator()); // return result; } /** * * @param toDup iterator of communication links to duplicate * @param nCopies number of copies to make * @return vector containing two copies of the iterator to * communication links. */ public static Vector > nDuplicateLinks(Iterator toDup, int nCopies) { Vector > result = new Vector< Iterator >(nCopies); Vector vec1 = new Vector (); while(toDup.hasNext()) { T nextLink = toDup.next(); vec1.add(nextLink); } result.add(vec1.iterator()); for(int i = 1; i < nCopies; ++i) { result.add(vec1.iterator()); } return result; } /** * Accumulates all the readable messages from a list of channels. * @param iterChannels iterator for channels to read from * @param msgBag initially empty bag to put messages into */ public static Collection accumMsgs( Iterator iterChannels, Collection msgBag) { while(iterChannels.hasNext()) { CommLink currLink = iterChannels.next(); IMsg msg = currLink.queue().readMsg(); msgBag.add((T)msg); } return msgBag; } public static Collection> zipMsgs(Iterator l1, Iterator l2, Collection> bag) { while(l1.hasNext() && l2.hasNext()) { bag.add(new MsgPair(l1.next(), l2.next())); } return bag; } /* * * @author mds * * @param * @param */ public static class MsgPair implements IMsg { T1 m_el1; T2 m_el2; public MsgPair() { } public MsgPair(T1 el1, T2 el2) { m_el1 = el1; m_el2 = el2; } public MsgPair makeCopy() { return new MsgPair(this.m_el1, this.m_el2); } public MsgPair(MsgPair src) { m_el1 = src.m_el1; m_el2 = src.m_el2; } public T1 getMsg1() { return m_el1; } public T2 getMsg2() { return m_el2; } } public static class MsgFilter implements Iterator { Iterator m_baseIter; IFuncObj m_filter; T m_msgFirst; boolean m_bExhausted; public MsgFilter(IFuncObj filter, Collection msgBag) { m_filter = filter; m_baseIter = msgBag.iterator(); m_msgFirst = null; } void pumpQueue() { boolean bPumped = false; while(m_baseIter.hasNext() && !bPumped) { m_msgFirst = (T)m_baseIter.next(); Boolean bCurrVal = m_filter.doFunc(m_msgFirst); bPumped = bCurrVal.booleanValue(); } if(!bPumped) { m_bExhausted = true; } } public boolean hasNext() { try { if(m_msgFirst == null) { pumpQueue(); } return !m_bExhausted; } catch(java.lang.ClassCastException e) { return false; } } public T next() { try { if(m_bExhausted) { return null; } if(m_msgFirst == null) { pumpQueue(); } T result = m_msgFirst; pumpQueue(); return result; } catch(java.lang.ClassCastException e) { return null; } } /** * unimplemented */ public void remove() { } } public static Iterator getFilteredMsgs(IFuncObj filter, Collection msgBag) { return new MsgFilter(filter, msgBag); } public static void applyFunc(IFuncObj func, Iterator iter) { while(iter.hasNext()) { func.doFunc(iter.next()); } } public int getCountMsg(IFuncObj filter, Collection msgBag) { Iterator iter = msgBag.iterator(); int nResult=0; while(iter.hasNext()) { IMsg currMsg = iter.next(); if(filter.doFunc(currMsg).booleanValue() == true) { ++nResult; } } return nResult; } /** * Message class to hold a position in n dimensions * @author mds * */ public static class PosMsg implements IMsg { double m_arrLfPos[]; public PosMsg() { m_arrLfPos = new double[2]; // default to 2d } public PosMsg(double [] arrLfPosArr, int nIdxStart, int nDim) { m_arrLfPos = new double[nDim]; for(int i = 0; i < nDim; ++i) { m_arrLfPos[i] = arrLfPosArr[nIdxStart+i]; } } public PosMsg(PosMsg src) { m_arrLfPos = new double[src.m_arrLfPos.length]; for(int i = 0; i < m_arrLfPos.length; ++i) { m_arrLfPos[i] = src.m_arrLfPos[i]; } } public PosMsg makeCopy() { return new PosMsg(this); } public double getDistSqrd(PosMsg posB) { double lfSum = 0.0; int nMax = Math.max(m_arrLfPos.length, posB.m_arrLfPos.length); for(int i = 0; i < nMax; ++i) { double lfTmp = m_arrLfPos[i] - posB.m_arrLfPos[i]; lfSum += lfTmp*lfTmp; } return lfSum; } public double getDist(PosMsg posB) { return Math.sqrt(getDistSqrd(posB)); } public double getPos(int i) { return m_arrLfPos[i]; } public double [] getPosArrCpy() { double [] arrLfOut = new double[m_arrLfPos.length]; for(int i = 0; i < m_arrLfPos.length; ++i) { arrLfOut[i] = m_arrLfPos[i]; } return arrLfOut; } public void setPosArr(double [] arrLfPosArr, int nIdxStart, int nDim) { m_arrLfPos = new double[nDim]; for(int i = 0; i < nDim; ++i) { m_arrLfPos[i] = arrLfPosArr[nIdxStart+i]; } } } /** * Empty message class. * @author mds * */ public static class NullMsg implements IMsg { public NullMsg makeCopy() { return this; // no need to explicitly copy!!! } } /** * Exists solely for testing purposes */ public class MsgIntWrapper implements IMsg { public int m_nVal; public MsgIntWrapper(int n) { m_nVal = n; } public MsgIntWrapper makeCopy() { return new MsgIntWrapper(m_nVal); } } /** * Exists solely for testing purposes */ public class FindMatching implements IFuncObj { int m_nValToMatch; public FindMatching(int nToMatch) { m_nValToMatch = nToMatch; } public Boolean doFunc(IMsg in) { MsgIntWrapper intMsg = (MsgIntWrapper)in; return new Boolean(intMsg.m_nVal == m_nValToMatch); } } /** * Helper for testing */ void printContentsIterTest(Iterator iter) { String strOut = "["; if(!iter.hasNext()) { strOut = strOut.concat("--empty--"); } while(iter.hasNext()) { IMsg msgNext = iter.next(); MsgIntWrapper intMsg = (MsgIntWrapper)msgNext; strOut = strOut.concat(" "+intMsg.m_nVal); } System.out.println(strOut+" ]"); } /** * Exists solely for testing purposes */ public boolean testFilters() { Vector collect = new Vector(); for(int i = 0; i < 10; ++i) { collect.add(i, new MsgIntWrapper(i)); } IFuncObj msgFindAll = new BoolFuncTrue(); IFuncObj msgFind0 = new FindMatching(0); IFuncObj msgFind5 = new FindMatching(5); IFuncObj msgFind8 = new FindMatching(8); IFuncObj msgFind9 = new FindMatching(9); IFuncObj msgFindAllBut25 = new BoolFuncAggregators.BoolFuncAnd ( new BoolFuncAggregators.BoolFuncNegate(new FindMatching(2)), new BoolFuncAggregators.BoolFuncNegate(new FindMatching(5)) ); Iterator iter0 = getFilteredMsgs(msgFind0, collect); Iterator iter5 = getFilteredMsgs(msgFind5, collect); Iterator iter8 = getFilteredMsgs(msgFind8, collect); Iterator iter9 = getFilteredMsgs(msgFind9, collect); Iterator iterAll = getFilteredMsgs(msgFindAll, collect); Iterator iterNot25 = getFilteredMsgs(msgFindAllBut25, collect); boolean bResult = iter0.hasNext() && iter5.hasNext() && iter8.hasNext() && iter9.hasNext() && iterNot25.hasNext(); System.out.println("Testing iter0"); printContentsIterTest(iter0); System.out.println("Testing iter5"); printContentsIterTest(iter5); System.out.println("Testing iter8"); printContentsIterTest(iter8); System.out.println("Testing iter9"); printContentsIterTest(iter9); System.out.println("Testing iterNot25"); printContentsIterTest(iterNot25); System.out.println("Testing iterAll"); printContentsIterTest(iterAll); bResult = bResult && !iter0.hasNext() && !iter5.hasNext() && !iter8.hasNext() && !iter9.hasNext() && !iterNot25.hasNext(); return bResult; } public static class appendIter implements Iterator { Iterator m_A, m_B; public appendIter(Iterator A, Iterator B) { m_A = A; m_B = B; } public boolean hasNext() { if((m_A != null && m_A.hasNext()) || (m_B != null && m_B.hasNext())) { return true; } return false; } public T next() { if(m_A != null && m_A.hasNext()) { return m_A.next(); } return m_B.next(); } /** * No clue what this method does -- leaving blank for now. */ public void remove() { // I have no idea what to do here } } public static class consIter implements Iterator { T m_A; boolean m_bAAvail; Iterator m_B; public consIter(T A, Iterator B) { m_A = A; m_B = B; m_bAAvail = true; } public boolean hasNext() { if(m_bAAvail || (m_B != null && m_B.hasNext())) { return true; } return false; } public T next() { if(m_bAAvail) { m_bAAvail = false; T tRes = m_A; m_A = null; return tRes; } return m_B.next(); } /** * No clue what this method does -- leaving blank for now. */ public void remove() { // I have no idea what to do here } } }