import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; import com.roboclub.robobuggy.ros.Message; import com.roboclub.robobuggy.ros.MessageListener; import com.roboclub.robobuggy.ros.Node; import com.roboclub.robobuggy.ros.Subscriber; public class BoundedQueueNumberSink implements Node { private Subscriber s; private Semaphore sem = new Semaphore(1); private AtomicInteger count = new AtomicInteger(1); public BoundedQueueNumberSink(String topicName, int numMessages) { this(topicName, numMessages, Integer.MAX_VALUE); } public BoundedQueueNumberSink(String topicName, int numMessages, int maxMessageQueueLength) { try { sem.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } s = new Subscriber("boundedSink", topicName, maxMessageQueueLength, new MessageListener() { @Override public void actionPerformed(String topicName, Message m) { IntegerMessage im = (IntegerMessage) m; int val = count.getAndIncrement(); if ((val + s.getNumberMessagesDropped())!= im.val) { System.out.println("For an bounded queue, the sum of dropped" + " messages and our counter must equal the published messages."); } if ((val+s.getNumberMessagesDropped()+1) == numMessages) { sem.release(); System.out.println("NumSink exiting..."); return; } } }); } public long getNumberMessagesDropped() { return s.getNumberMessagesDropped(); } @Override public boolean shutdown() { s.close(); return true; } @Override public boolean startNode() { return false; } @Override public void setName(String newName) { System.out.println("tried to set name"); } @Override public String getName() { return null; } public int blockUntilDone() { try { sem.acquire(); } catch (InterruptedException e) { assert (false); } return count.get() + (int)getNumberMessagesDropped(); } }