/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2005, by :
* Corporate:
* EADS Astrium SAS
* EADS CRC
* Individual:
* Claude Cazenave
*
* $Id: CircuitConnection.java,v 1.3 2008/10/24 15:51:36 ogor Exp $
*
* Changes
* -------
* 08 sept 2008 : Initial public release (RO);
*
*/
package jsynoptic.plugins.circuit;
import java.awt.Color;
import simtools.diagram.gate.Gate;
import simtools.shapes.AbstractShape;
import simtools.shapes.StrokeParameters;
import jsynoptic.builtin.ConnectionShape;
import jsynoptic.builtin.ui.StrokeDisplay;
/**
* A Circuit Connector is able to propagate a signal between the gates it is connected to.
*
* Whenever a gate receives a signal
* <ul>
* <li>The connector is colored with the signal color
* <li>The signal is forwarded to the other gate
* </ul>
*
* @author zxpletran007
*
*/
public class CircuitConnection extends ConnectionShape {
private static final long serialVersionUID = -7813494028034947644L;
protected transient Color connectionColor = null;
public Color getConnectionColor() {
return connectionColor;
}
public CircuitConnection(int x, int y, int w, int h) {
this(x, y, w, h, null, null);
}
public CircuitConnection(int x, int y, int w, int h, CircuitGate fisrtGate, CircuitGate lastGate) {
super(x, y, w, h, fisrtGate, lastGate);
// Set stroke thickness to 2 for circuit connectors...
StrokeParameters strockeParam = StrokeDisplay.defaultstrokes[0].getStrokeParams();
strockeParam.setThickness(2);
stroke = StrokeParameters.createStroke(strokeParams.param1, strokeParams.param2, strokeParams.thickness);
this.connectionColor = null;
}
/* (non-Javadoc)
* @see simtools.shapes.AbstractShape#cloneShape()
*/
protected AbstractShape cloneShape() {
CircuitConnection cs = (CircuitConnection)super.cloneShape();
cs.connectionColor = null;
return cs;
}
/* (non-Javadoc)
* @see jsynoptic.builtin.Abstract1DShape#getDrawColor()
*/
public Color getDrawColor(){
return (connectionColor!=null) ? connectionColor : super.getDrawColor();
}
/**
* The given gate has a new signal.
* Propagate the signal on the connection
* @param gate - The gate that holds the new signal
*/
public void signalHasChanged(CircuitGate sourceGate) {
processSignalNotification(sourceGate.getCurrentSignal(), sourceGate.currentSignalEventId, sourceGate);
}
/**
* Propagate the signal from one gate to the other one
* Update the connector according to signal value.
*/
/**
* Propagate a received signal on the connector
* @param signal
* @param signalEventId
* @param firstBound - if true signal has been received on first bound, otherwise on last bound
*/
protected void processSignalNotification(Signal signal, int signalEventId, CircuitGate sourceGate){
if (isConnected(sourceGate)){
Color oldDrawColor = getDrawColor();
if (signal == null){
connectionColor = null;
} else if (signal instanceof ColoredSignal){
connectionColor = ((ColoredSignal)signal).getColor();
}
// Do a redraw only when necessary
boolean dirtyGateColor = !getDrawColor().equals(oldDrawColor);
if (dirtyGateColor) {
notifyChange(dirtyRectangle); // may have been set by children
dirtyRectangle = null; // take all bounds next time
dirty = false;
}
// Forward signal to the orther gate
CircuitGate otherGate = (CircuitGate) ( (sourceGate==fisrtGate)? lastGate : fisrtGate );
if (otherGate != null){
otherGate.receiveSignal(signal, signalEventId);
}
}
}
/* Connect a connector bound to a gate.
* @param gate - The gate to be attached
* @param onfirstBound - If true attach the first bound, otherwise attach the last bound.
*/
public void connect(Gate gate, boolean onfirstBound) {
// Proceed to the connection only if the target gate allows the connection with the other gate
if (gate != null
&& gate.allowConnection(onfirstBound? lastGate : fisrtGate)
&& gate instanceof CircuitGate
){
super.connect(gate, onfirstBound);
// Update listeners
CircuitGate circuitGate = (CircuitGate)gate;
if (onfirstBound){
fisrtGate = circuitGate;
}else {
lastGate = circuitGate;
}
// Propagate a signal
if (circuitGate.isInput()){
// propagate the other gate current signal and forward it to this gate
CircuitGate otherGate = (CircuitGate)(onfirstBound? lastGate : fisrtGate);
if (otherGate != null && otherGate.hasSignal()){
circuitGate.receiveSignal(otherGate.currentSignal, otherGate.currentSignalEventId);
}
} else {
if (circuitGate.hasSignal()){
signalHasChanged(circuitGate);
}
}
}
}
/**
* Disconnect the bound from its attached gate
* @param firstBound
*/
public void disconnect(Gate gate){
if (isConnected(gate)){
// Forward a null signal
if ( ((CircuitGate)gate).isInput()){
((CircuitGate)gate).receiveSignal(null, Signal.getNewSignalEventId());
} else {
processSignalNotification(null, Signal.getNewSignalEventId(), (CircuitGate)gate);
}
}
super.disconnect(gate);
}
}