📄 port.java
字号:
/*
|
| Port.java
|
| Port class
| James Shin Young
|
| Created: December 12, 1997
|
| Copyright (c) 1997 by James Shin Young and the Regents
| of the University of California. All rights reserved.
|
| Permission to use, copy, modify, and distribute this software
| and its documentation for NON-COMMERCIAL purposes and without
| fee is hereby granted provided that this copyright notice
| appears in all copies.
|
*/
package jcp;
import java.util.Enumeration;
/**
* @author James Shin Young
* @see Component
*/
public class Port
{
private static Class defaultType;
static {
try {
defaultType = java.lang.Class.forName("java.lang.Object");
} catch (ClassNotFoundException e) {
JTSystem.error("java.lang.Object not found!");
}
}
///////////////////////////////////////////////////////////////////////////////
//* Private variables
/**
* The component that this port is associated with.
*/
private Component owner;
/**
* Flag if this port triggers a component behavior, or whether
* it simply forwards its value to its receivers.
* true = works in conjunction with a component's activate() method
* false = simple signal pass-through
*/
private boolean active;
/**
* The current value of the signal.
*/
private Object signal;
/**
* The type of the signals that are accepted by this port.
*/
private Class type;
/**
* Vector of the port's sources.
*/
private PortSet sources;
/**
* Vector of the port's receivers.
*/
private PortSet receivers;
/**
* This port's name.
*/
private String name;
///////////////////////////////////////////////////////////////////////////////
//* Constructors
/**
* Creates a new port. The signal value is initialized to Signal.UNDEFINED.
* @param owner The port's owner.
* @param name The port's name.
* @param type The signal type to be accepted by the port.
* @param active true if the port is to be active, false if inactive.
*/
public Port(Component owner, String name, Class type, boolean active) {
this.owner = owner;
setName(name);
this.type = type;
this.active = active;
sources = new PortSet();
receivers = new PortSet();
if (this.type == null) {
this.type = defaultType;
}
// When created, ports start with the value UNDEFINED
// This helps avoid null pointer exceptions everywhere
signal = Signal.UNDEFINED;
}
///////////////////////////////////////////////////////////////////////////////
//* Static methods
/**
* Connects a port to another port.
*
* @param source The port that will serve as the source.
* @param receiver The port that will serve as the receiver.
*/
public static void connect(Port source, Port receiver) {
receiver.connectAsReceiver(source);
}
/**
* Severs the connection between two ports.
* @param source The source port.
* @param receiver The receiver port.
*/
public static void disconnect(Port source, Port receiver) {
receiver.disconnectAsReceiver(source);
}
///////////////////////////////////////////////////////////////////////////////
//* Public methods
/**
* Returns this port's owner.
*/
public final Component owner() { return owner; }
/**
* Returns an enumeration of this port's sources.
*/
public final java.util.Enumeration sources() { return sources.ports(); }
/**
* Returns the number of sources this port has.
*/
public final int numSources() {
return sources.size();
}
/**
* Returns an enumeration of this port's receivers.
*/
public final java.util.Enumeration receivers() { return receivers.ports(); }
/**
* Returns the number of receivers this port has.
*/
public final int numReceivers() {
return receivers.size();
}
/**
* Sends a signal to the port.
* @param signal The signal to be assigned to the port.
*/
public boolean emit(Object signal) {
if (type.isInstance(signal)) {
if (active == true) {
return owner.activate(this,signal);
} else if (!signal.equals(this.signal)) {
updateSignal(signal);
return true;
} else {
return true;
}
} else {
return false;
}
}
/**
* Returns the signal contained by the port.
* @return The current value of the port. Returns Signal.UNDEFINED
* if no signal has yet been assigned to it.
*/
public final Object signal() {
return signal;
}
/**
* Resets the value of the port to be Signal.UNDEFINED.
*/
public void reset() {
signal = Signal.UNDEFINED;
}
/**
* @return true if the signal is not Signal.UNDEFINED.
*/
public boolean defined() {
return (signal != Signal.UNDEFINED);
}
/**
* @return The class of objects that this port accepts as signals.
*/
public Class type() { return type; }
/**
* Sets the class of objects that this port accepts as signals.
* Signals not of the designated class or one of its subclasses are
* ignored.
*/
public void setType(Class type) {
this.type = type;
}
/**
* @return true if the port is active, false if inactive.
* Active ports will cause the owning components to react. Inactive
* ports will not.
*/
public boolean active() { return active; }
/**
* Sets the port to be active/inactive.
* @param active true if active, false if inactive.
*/
public void setActive(boolean active) {
this.active = active;
}
/**
* @return The name of this port.
*/
public String name() { return name; }
/**
* Sets the name of this port.
* @param name The new name.
*/
public void setName(String name) { this.name = name; }
public String toString() {
return name+":"+super.toString();
}
public void disconnectAll() {
while (receivers.size() > 0) {
disconnect(this,receivers.elementAt(0));
}
while (sources.size() > 0) {
disconnect(sources.elementAt(0),this);
}
}
///////////////////////////////////////////////////////////////////////////////
//* Protected methods
/**
* Connects this port as a receiver of the specified port
* @return false if connection between these ports is not allowed,
* true otherwise.
*/
protected final void connectAsReceiver(Port port) {
port.addReceiver(this);
this.addSource(port);
this.updateSignal(port.signal());
}
/**
* Disconnects this port as a receiver of the specified port
* @return false if connection between these ports is not allowed,
* true otherwise.
*/
protected final void disconnectAsReceiver(Port port) {
port.removeReceiver(this);
this.removeSource(port);
}
/**
* Adds a source to this port.
* @param port The port to be connected to this port.
*/
protected final synchronized void addSource(Port port) {
sources.add(port);
}
/**
* Removes a source from this port.
* @param port The port to be disconnected from this port.
*/
protected final synchronized void removeSource(Port port) {
sources.remove(port);
}
/**
* Adds a receiver to this port.
* @param port The port to be connected to this port.
*/
protected final synchronized void addReceiver(Port port) {
receivers.add(port);
}
/**
* Removes a receiver from this port.
* Does nothing if the port specified is not a receiver.
* @param port The port to be disconnected from this port.
*/
protected final synchronized void removeReceiver(Port port) {
receivers.remove(port);
}
/**
* Updates the signal stored by this port.
*/
protected final synchronized void updateSignal(Object signal) {
// Check to see if the signal is of a type that we care about
if (type.isInstance(signal)) {
this.signal = signal;
updateReceivers();
}
}
///////////////////////////////////////////////////////////////////////////////
//* Private methods
// Updates all receivers of this port's new value. Called from
// the assign method.
private final void updateReceivers() {
for (int i=0; i < receivers.size(); i++) {
receivers.elementAt(i).emit(signal);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -