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
}
}
}