001    package edu.nrao.sss.electronics;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    /**
007     * A device that takes an input signal and replicates it on all of
008     * its outputs.
009     * <p>
010     * <b>Version Info:</b>
011     * <table style="margin-left:2em">
012     *   <tr><td>$Revision: 1006 $</td></tr>
013     *   <tr><td>$Date: 2007-11-16 11:19:54 -0700 (Fri, 16 Nov 2007) $</td></tr>
014     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
015     * </table></p>
016     * 
017     * @author David M. Harland
018     * @since 2007-10-24
019     */
020    public class SignalManifold
021      implements SignalProcessor, SignalSource
022    {
023      private SignalPipe       inputPipe;
024      private List<SignalPipe> outputPipes;
025    
026      //============================================================================
027      // OBJECT CREATION
028      //============================================================================
029    
030      /**
031       * Creates a new manifold with the given number of outputs.
032       * 
033       * @param numberOfOutputs
034       *   the number of outputs eminating from this manifold.
035       *   
036       * @throws IllegalArgumentException
037       *   if {@code numberOfOutputs} is negative.
038       */
039      public SignalManifold(int numberOfOutputs)
040      {
041        inputPipe = SignalPipe.makeAndWeldOutputTo(this);
042    
043        outputPipes = new ArrayList<SignalPipe>(numberOfOutputs);
044        
045        for (int p=0; p < numberOfOutputs; p++)
046          outputPipes.add(SignalPipe.makeAndWeldInputTo(this));
047      }
048    
049      //============================================================================
050      // 
051      //============================================================================
052    
053      /**
054       * Returns the number of outputs from this manifold.
055       * @return the number of outputs from this manifold.
056       */
057      public int getNumberOfOutputs()
058      {
059        return outputPipes.size();
060      }
061      
062      /**
063       * Returns the input pipe of this device.
064       * A typical usage pattern for this method is:<pre>
065       * myFork.getInputPipe().connectInputTo(mySource);</pre>
066       * 
067       * @return the input pipe of this device.
068       */
069      public SignalPipe getInputPipe()
070      {
071        return inputPipe;
072      }
073      
074      /**
075       * Returns the {@code index}<sup>th</sup> output pipe of this device.
076       * A typical usage pattern for this method is:<pre>
077       * myFork.getOutputPipe(p).connectOutputTo(myProcessor);</pre>
078       * <p>
079       * Indexing begins at zero.</p>
080       * 
081       * @return the {@code index}<sup>th</sup> output pipe of this device.
082       */
083      public SignalPipe getOutputPipe(int index)
084      {
085        return outputPipes.get(index);
086      }
087      
088      //============================================================================
089      // INTERFACE SignalSource
090      //============================================================================
091      
092      /**
093       * Returns the signal provided by the input pipe of this device.
094       * If nothing is connected to the input pipe, or if the connected
095       * source has a <i>null</i> signal, <i>null</i> will be returned.
096       */
097      public Signal getSignal()
098      {
099        return inputPipe.getSignal();
100      }
101    
102      //============================================================================
103      // INTERFACE SignalProcessor
104      //============================================================================
105    
106      /**
107       * Executes the output pipes of this device.
108       */
109      public void execute()
110      {
111        for (SignalPipe outputPipe : outputPipes)
112          outputPipe.execute();
113      }
114      
115      public void executeUpTo(SignalProcessor firstUnexecutedDevice)
116      {
117        //Quick exit if execution should not occur
118        if (firstUnexecutedDevice == this)
119          return;
120    
121        for (SignalPipe outputPipe : outputPipes)
122          outputPipe.executeUpTo(firstUnexecutedDevice);
123      }
124    
125      public void executeFromStartOfChainUpTo(SignalProcessor firstUnexecutedDevice)
126      {
127        inputPipe.executeFromStartOfChainUpTo(firstUnexecutedDevice);
128      }
129    }