package xapi.util.impl; import xapi.collect.api.Fifo; import xapi.collect.impl.SimpleFifo; import xapi.util.api.ReceivesValue; /** * An extension of {@link ReceivesMultiValue} which uses three prioritized callback buckets. * <br/><br/> * * {@link #addPre(ReceivesValue, boolean)} - * pushes callback onto stack called before all others. * Send true to push on head of pre stack * <br/><br/> * * {@link #addPost(ReceivesValue)} - * pushes callback onto bottom of the stack called after all others. * Send true to push on head of pre stack * <br/><br/> * * {@link #addToHead(ReceivesValue)} - * push callback on top of main callback stack * <br/><br/> * * {@link #addReceiver(ReceivesValue)} - * push callback on bottom of main callback stack * <br/><br/> * * @author James X. Nelson (james@wetheinter.net, @james) * * @param <T> */ public class ReceivesPrioritizedValue<T> extends ReceivesMultiValue<T>{ //our extra callback stacks final Fifo<ReceivesValue<T>> pre = new SimpleFifo<ReceivesValue<T>>(); final Fifo<ReceivesValue<T>> post = new SimpleFifo<ReceivesValue<T>>(); /** * Adds a callback that will be fired before the main and post callback stacks * * @param receiver - The receiver to add to pre-fire stack * @param top - true to unshift onto head, false to push onto tail */ public void addPre(ReceivesValue<T> receiver){ assert receiver != null : "Do not send null receivers to "+this+"; (ReceivesMultiValue.addBefore) "; assert receiver != this : "Do not send a ReceivesMultiValue to itself. Class: "+this+";"; pre.give(receiver); } /** * Adds a callback that will be fired after the pre and main callback stacks * * @param receiver - The receiver to add to pre-fire stack * @param top - true to unshift onto head, false to push onto tail */ public void addPost(ReceivesValue<T> receiver){ assert receiver != null : "Do not send null receivers to "+this+"; (ReceivesMultiValue.addAfter) "; assert receiver != this : "Do not send a ReceivesMultiValue to itself. Class: "+this+";"; post.give(receiver); } /** * Send an object to all of our callbacks, in prioritized order. */ @Override public void set(T value) { for (ReceivesValue<T> receiver : pre.forEach()){ receiver.set(value); } for (ReceivesValue<T> receiver : handlers.forEach()){ receiver.set(value); } for (ReceivesValue<T> receiver : post.forEach()){ receiver.set(value); } }; /** * Clear all callback stacks. */ @Override public void clearReceivers() { super.clearReceivers(); post.clear(); pre.clear(); } /** * Explicitly remove the given receiver from all callback stacks. */ @Override public void removeReceiver(ReceivesValue<T> receiver) { super.removeReceiver(receiver); pre.remove(receiver); post.remove(receiver); } }