/* A CSP actor that continually performs conditional rendezvous in
an alternating fashion with its input and output ports.
Copyright (c) 1998-2005 The Regents of the University of California.
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the above
copyright notice and the following two paragraphs appear in all copies
of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
PT_COPYRIGHT_VERSION_2
COPYRIGHTENDKEY
*/
package ptolemy.domains.csp.demo.BusContention;
import ptolemy.actor.Receiver;
import ptolemy.actor.TypedIOPort;
import ptolemy.actor.process.TerminateProcessException;
import ptolemy.data.StringToken;
import ptolemy.data.type.BaseType;
import ptolemy.domains.csp.kernel.CSPActor;
import ptolemy.domains.csp.kernel.ConditionalBranch;
import ptolemy.domains.csp.kernel.ConditionalReceive;
import ptolemy.domains.csp.kernel.ConditionalSend;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
//////////////////////////////////////////////////////////////////////////
//// Memory
/**
A CSP actor that continually performs conditional rendezvous in
an alternating fashion with its input and output ports. The Memory
actor can optionally send tokens with string values during
conditional rendezvous.
@author John S. Davis II
@version $Id$
@since Ptolemy II 0.3
@Pt.ProposedRating Red (davisj)
@Pt.AcceptedRating Red (cxh)
*/
public class Memory extends CSPActor {
/** Construct a Memory actor with the specified container
* and name.
* @param cont The container of this actor.
* @param name The name of this actor.
* @exception IllegalActionException If the actor cannot be
* contained by the proposed container.
* @exception NameDuplicationException If the container
* already has an actor with this name.
*/
public Memory(CompositeEntity cont, String name)
throws IllegalActionException, NameDuplicationException {
super(cont, name);
input = new TypedIOPort(this, "input", true, false);
output = new TypedIOPort(this, "output", false, true);
input.setMultiport(true);
output.setMultiport(true);
input.setTypeEquals(BaseType.STRING);
output.setTypeEquals(BaseType.GENERAL);
_strValue = "initialValue";
}
///////////////////////////////////////////////////////////////////
//// ports and parameters ////
/** The input port. The type of this port is BaseType.STRING.
* This is a multiport.
*/
public TypedIOPort input;
/** The output port. The type of this port is BaseType.GENERAL.
* This is a multiport.
*/
public TypedIOPort output;
///////////////////////////////////////////////////////////////////
//// public methods ////
/** Execute this actor indefinitely unless there is an error
* during one of the conditional rendezvous attempts.
* @exception IllegalActionException If there is an error
* during communication via the ports.
*/
public void fire() throws IllegalActionException {
super.fire();
if (_numInChannels == -1) {
_numInChannels = 0;
Receiver[][] rcvrs = input.getReceivers();
for (int i = 0; i < rcvrs.length; i++) {
for (int j = 0; j < rcvrs[i].length; j++) {
_numInChannels++;
}
}
}
if (_numOutChannels == -1) {
_numOutChannels = 0;
Receiver[][] rcvrs = output.getRemoteReceivers();
for (int i = 0; i < rcvrs.length; i++) {
for (int j = 0; j < rcvrs[i].length; j++) {
_numOutChannels++;
}
}
}
StringToken token;
while (true) {
token = new StringToken(_strValue);
int numBranches = _numInChannels + _numOutChannels;
ConditionalBranch[] branches = new ConditionalBranch[numBranches];
// Receive Branches
for (int i = 0; i < _numInChannels; i++) {
branches[i] = new ConditionalReceive(true, input, i, i);
}
// Send Branches
for (int i = 0; i < _numOutChannels; i++) {
branches[i + _numInChannels] = new ConditionalSend(true,
output, i, i + _numInChannels, token);
}
int br = chooseBranch(branches);
// Sleep so that graphical displays involving this
// applet will pause after colors are changed.
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new TerminateProcessException(this, "Terminated");
}
if ((br >= 0) && (br < _numInChannels)) {
token = (StringToken) branches[br].getToken();
_strValue = token.toString();
} else if ((br >= _numInChannels) && (br < numBranches)) {
_strValue = "write";
} else if (br == -1) {
return;
}
}
}
/** Return the value of the string that is associated with
* the input token.
* @return The String value of the input token.
*/
public synchronized String getString() {
return _strValue;
}
///////////////////////////////////////////////////////////////////
//// public variables ////
private int _numInChannels = -1;
private int _numOutChannels = -1;
private String _strValue = null;
}