package kukaWii.wiiHandle.provider; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import kukaWii.wiiHandle.consumer.IPacketConsumer; import kukaWii.wiiHandle.filter.AbstractPacketFilter; import kukaWii.wiiHandle.packet.AbstractPacket; /** * Abstrakte Klasse, um WiiPakete anzubieten. * Dazu muss die Methode providePacket genutzt werden. * @author Kai * */ public abstract class AbstractPacketProvider { private BlockingQueue<AbstractPacket> out = new ArrayBlockingQueue<AbstractPacket>(100, true); private Lock providerLock = new ReentrantLock(true); private IPacketConsumer consumer = null; private IPacketConsumer lastConsumer = null; private boolean interrupt = false; /** * Methode, um ein Packet in die OutputQueue zu schieben * @param packet */ protected void providePacket(AbstractPacket packet){ providerLock.lock(); try{ //Ermöglicht eine Zirkulation der Pakete, wenn kein Verbrauch stattfindet. if(!interrupt){ if(!out.offer(packet)){ out.poll(); out.offer(packet); } } }finally{ providerLock.unlock(); } } /** * Fügt ans Ende der Kette einen Consumer an. * In folgender Reihenfolge können hinzugefügt werden: * - n Filter * - 1 Consumer * @param consumer */ public void addConsumer(IPacketConsumer consumer){ lastConsumer = consumer; if(this.consumer != null){ ((AbstractPacketProvider)this.consumer).addConsumer(consumer); }else{ this.consumer = consumer; this.consumer.registerQueue(out); this.consumer.start(); } } /** * Notfallinterrupt, nur durch Exception aufzurufen! */ public void panicInterrupt(){ lastConsumer.stop(); this.consumer.stop(); } /** * Zum temporären unterbrechen des Paketstromes. * Alle Pakete werden ab hier gedropt. */ public void interrupt(){ this.interrupt=true; } /** * Ab diesem Aufruf werden wieder Pakete erzeugt. */ public void uninterrupt(){ this.interrupt=false; } }