Package jsynoptic.plugins.circuit.switches

Source Code of jsynoptic.plugins.circuit.switches.Switch$SwitchShapePropertiesNames

/* ========================
* 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: Switch.java,v 1.5 2009/01/15 12:29:08 ogor Exp $
*
* Changes
* -------
* 08 sept 2008 : Initial public release (RO);
*
*/
package jsynoptic.plugins.circuit.switches;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.swing.undo.CompoundEdit;

import simtools.data.DataException;
import simtools.data.DataSource;
import simtools.data.DataSourcePool;
import simtools.data.UnsupportedOperation;
import simtools.diagram.gate.Connection;
import simtools.diagram.gate.Gate;
import simtools.shapes.AbstractShape;
import simtools.shapes.undo.PropertyChangeEdit;
import simtools.ui.JPropertiesPanel;

import jsynoptic.base.DataSourceConsumer;
import jsynoptic.plugins.circuit.Abstract2DCircuitComponent;
import jsynoptic.plugins.circuit.CircuitGate;
import jsynoptic.plugins.circuit.CircuitPlugin;
import jsynoptic.plugins.circuit.ColoredSignal;
import jsynoptic.plugins.circuit.Signal;
import jsynoptic.plugins.circuit.ui.SwitchShapePropertiesPanel;


/**
*
* A switch is a circuit component composed of several gates that can be connected, according
* to a switch position.
*
* @author zxpletran007
*
*/
public abstract class Switch extends Abstract2DCircuitComponent implements DataSourceConsumer{

    private static final long serialVersionUID = -7002331688071008405L;

    /**
     * Arc and lines inside the switch component that represents the connections between switch gates
     */
    protected transient List switchInnerConnections;

    protected transient boolean dirtyPosition = false;
    protected transient DataSource switchPositionDs;
    protected transient long switchPositionDsIndex;

    /**
     * Switch default position
     */
    protected int defaultPosition;

    /**
     * Switch current position
     */
    protected int currentPosition;

    /**
     * @param ox
     * @param oy
     * @param diameter
     * @param defaultPosition
     */
    public Switch(int ox, int oy, int width, int height, int defaultPosition) {
        super(ox, oy, width, height);
        this.defaultPosition = defaultPosition;
        this.currentPosition = defaultPosition;
        this.switchInnerConnections = new ArrayList();
    }


    /* (non-Javadoc)
     * @see jsynoptic.builtin.Abstract1DShape#drawHook(java.awt.Graphics2D, boolean)
     */
    protected void drawHook(Graphics2D g, boolean shapeDrawn) {
        if (!shapeDrawn) {
            return;
        }

        Object oldRendering = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Draw switch connections
        for(int i=0;i< switchInnerConnections.size();i++){
            ((SwitchInnerConnection) switchInnerConnections.get(i)).draw(g);
        }

        // Draw switch circle
        g.draw(getSwitchFrame());

        // Restore graphic properties
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldRendering);
    }


    protected void fillHook(Graphics2D g) {
        Color c = getFillColor();
        if (c!=null) {
            g.setColor(c);
            g.fill(getSwitchFrame());
        }
    }

    /**
     * Create switch connections according to current switch position
     */
    protected abstract void updateSwitchInnerConnections();


    /**
     * Get the switch frame
     * @return
     */
    protected abstract Shape getSwitchFrame();


    /* (non-Javadoc)
     * @see jsynoptic.builtin.SimpleShape#getDelegateShape()
     */
    protected Shape getDelegateShape() {
        return null;
    }


    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#translate(int, int)
     */
    public void translate(int dx, int dy) {
        super.translate(dx, dy);

        for(int i=0;i< switchInnerConnections.size();i++){
            ((SwitchInnerConnection) switchInnerConnections.get(i)).translate(dx, dy);
        }
    }


    /* (non-Javadoc)
     * @see simtools.diagram.Resizable#resize(int, int)
     */
    public void resize(int dx, int dy) {
        super.resize(dx, dy);

        for(int i=0;i< switchInnerConnections.size();i++){
            ((SwitchInnerConnection) switchInnerConnections.get(i)).resize(dx, dy);
        }
    }
   
    /**
     * Update switch according to current bounding box
     */
    public void updateSwitch(){
        for(int i=0;i< switchInnerConnections.size();i++){
            ((SwitchInnerConnection) switchInnerConnections.get(i)).updateConnector();
        }
    }


    /* (non-Javadoc)
     * @see simtools.data.EndNotificationListener#notificationEnd(java.lang.Object)
     */
    public void notificationEnd(Object referer) {
        if (dirtyPosition) {
            dirty |= setSwitchPosition(getDynamicSwichPosition());
            dirtyPosition = false;
        }
        // parent for colors & update
        super.notificationEnd(referer);
    }

    /**
     * @return the switch position from the current dynamic SVG data source.
     * Return the default position if the current data source value is not a valid position
     */
    protected int getDynamicSwichPosition() {
        int res = defaultPosition;
        if ((switchPositionDs != null)) {
            Object o;
            try {
                o = getSourceValue();
                if (o instanceof Number){
                    int newpos =  ((Number)o).intValue();
                    if (isValidPosition(newpos)){
                        res = newpos;
                    }
                }
            } catch (DataException e) {
            }
        }
        return res;
    }


    protected Object getSourceValue() throws DataException {
        if (switchPositionDs != null) {
            return switchPositionDs.getValue(switchPositionDsIndex);
        }
        return null;
    }

    /**
     * Set switch position
     * @param newPosition
     * @return true if switch position has changed
     */
    public boolean setSwitchPosition(int newPosition){
        boolean res = false;

        if ( isValidPosition(newPosition) && newPosition != currentPosition){ 
            res = true;
            currentPosition = newPosition;

            // 1- Update switch inner connections
            updateSwitchInnerConnections();

            // 2- Propagate signal

            // All output gates forward a null signal 
            Iterator it = getGates().iterator();
            while (it.hasNext()){
                CircuitGate gate = (CircuitGate)it.next();
                if (gate!=null && !gate.isInput()){
                    gate.sendSignal(null,Signal.getNewSignalEventId());
                }
            }

            // All input gates forward their signal to output gates
            it = getGates().iterator();
            while (it.hasNext()){
                CircuitGate gate = (CircuitGate)it.next();
                if (gate!=null &&  gate.isInput() && gate.hasSignal()){
                    signalHasBeenReceived(gate);
                }
            }
        }
        return res;
    }



    /**
     * @return <b>(boolean)</b>  A boolean. True if the given position is a valid switch position.
     * Shall be overloaded in subclasses, regarding the kind of switches.
     */
    protected abstract boolean isValidPosition(int position);



    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceIndexRangeChanged(simtools.data.DataSource, long, long)
     */
    public void DataSourceValueChanged(DataSource ds, long minIndex, long maxIndex) {

        if (ds.equals(switchPositionDs)) {
            if ((switchPositionDsIndex >= minIndex) && (switchPositionDsIndex <= maxIndex)){
                dirtyPosition = true;
            }
        }
        super.DataSourceValueChanged(ds, minIndex, maxIndex);
    }

    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceValueChanged(simtools.data.DataSource, long, long)
     */
    public void DataSourceIndexRangeChanged(DataSource ds, long startIndex, long lastIndex) {

        if (ds.equals(switchPositionDs)) {
            switchPositionDsIndex = lastIndex;
            dirtyPosition = true;
        }
        super.DataSourceIndexRangeChanged(ds, startIndex, lastIndex);
    }

    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceReplaced(simtools.data.DataSource, simtools.data.DataSource)
     */
    public void DataSourceReplaced(DataSource oldData, DataSource newData) {
        if(oldData==switchPositionDs){
            switchPositionDs=newData;

            if (switchPositionDs!=null) {
                switchPositionDs.addListener(this);
                switchPositionDs.addEndNotificationListener(this);
                try {
                    switchPositionDsIndex = switchPositionDs.getLastIndex();
                } catch (UnsupportedOperation uo1) {
                    switchPositionDsIndex = 0;
                }
            }
            oldData.removeListener(this);
            oldData.removeEndNotificationListener(this);
            dirtyPosition = true;
        }
        super.DataSourceReplaced(oldData,newData);
    }

    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.base.DataSourceConsumer#addDataSource(simtools.data.DataSource)
     */
    public boolean addDataSource(DataSource ds) {
        setSwitchPositionDs(ds);
        notifyChange();    
        return true;
    }

    /**
     * Set switch position data source reference
     * @param ds - the data source (can be null)
     */
    protected void setSwitchPositionDs(DataSource ds){
       
        if (switchPositionDs != null) {
            // if there is already a source for this shape,
            // remove it
            switchPositionDs.removeListener(this);
            switchPositionDs.removeEndNotificationListener(this);
        }
       
        switchPositionDs = ds;
       
        if (ds instanceof DataSource) {
            try {
                switchPositionDsIndex = switchPositionDs.getLastIndex();
            } catch (UnsupportedOperation e) {
                switchPositionDsIndex = 0;
            }
            switchPositionDs.addListener(this);
            switchPositionDs.addEndNotificationListener(this);
        }
        setSwitchPosition(getDynamicSwichPosition());
    }

    public int getCurrentPosition() {
        return currentPosition;
    }


    /* (non-Javadoc)
     * @see simtools.diagram.gate.GatedComponent#connectionAddedAt(simtools.diagram.gate.Gate, simtools.diagram.gate.Connection)
     */
    public void connectionAddedAt(Gate gate, Connection connection) {  

        // If the other connection gate  holds a signal, the given gate becomes an input of this component
        Gate otherGate = null;
        if (connection.getFirstEndGate() != null && !connection.getFirstEndGate().equals(gate)){
            otherGate = connection.getFirstEndGate();

        } else if (connection.getLastEndGate() != null && !connection.getLastEndGate().equals(gate)){
            otherGate = connection.getLastEndGate();
        }

        if (otherGate != null
                && otherGate instanceof CircuitGate
                &&  ((CircuitGate)otherGate).hasSignal()
        ){
            ((CircuitGate)gate).setInput(true);
        }
    }


    /* (non-Javadoc)
     * @see simtools.diagram.gate.GatedComponent#connectionRemovedAt(simtools.diagram.gate.Gate, simtools.diagram.gate.Connection)
     */
    public void connectionRemovedAt(Gate gate, Connection connection) {
    }

    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#subscribeToDataNotifications()
     */
    public void processShapeRestoring(){
        if (switchPositionDs!=null) {
            switchPositionDs.addListener(this);
            switchPositionDs.addEndNotificationListener(this);
            try {
                switchPositionDsIndex = switchPositionDs.getLastIndex();
            } catch (UnsupportedOperation uo1) {
                switchPositionDsIndex = 0;
            }
        }
        super.processShapeRestoring();
    }


    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#unsubscribeToDataNotifications()
     */
    public void processShapeRemoving(){
        if (switchPositionDs != null) {
            switchPositionDs.removeListener(this);
            switchPositionDs.removeEndNotificationListener(this);
        }
        super.processShapeRemoving();
    }



    //  Take care of serialisation. Special handling for datasources
    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
        out.defaultWriteObject();
        DataSourcePool.global.writeDataSource(out, switchPositionDs);
    }

    private void readObject(java.io.ObjectInputStream in) throws java.lang.ClassNotFoundException, java.io.IOException {
        in.defaultReadObject();

        switchPositionDs = DataSourcePool.global.readDataSource(in);
        if (switchPositionDs!=null)
            try {
                switchPositionDs.addListener(this);
                switchPositionDs.addEndNotificationListener(this);
                switchPositionDsIndex= switchPositionDs.getLastIndex();
            }
        catch (UnsupportedOperation uo1) {
            switchPositionDsIndex = 0;
       
        currentPosition = getDynamicSwichPosition();
       
        switchInnerConnections = new ArrayList();
    }

    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#cloneShape()
     */
    protected AbstractShape cloneShape() {
        Switch es = (Switch)super.cloneShape();

        es.gateHolder =  gateHolder.cloneGateHolder(es);

        // Switch inner connections
        es.switchInnerConnections = new ArrayList();
        for(int i=0;i<switchInnerConnections.size();i++){
            SwitchInnerConnection sc=(SwitchInnerConnection)switchInnerConnections.get(i);
          
            try {
                es.switchInnerConnections.add( es.cloneSwitchConnection(sc) );
            } catch (InvalidSwitchConnection e) {
                e.printStackTrace();
            }
        }

        if(es.switchPositionDs!=null){
            es.switchPositionDs.addEndNotificationListener(es);
            es.switchPositionDs.addListener(es);
        }
        return es;
    }



    //***** GateComponent methods

    /* (non-Javadoc)
     * @see jsynoptic.plugins.circuit.CircuitComponent#gateSignalHasChanged(jsynoptic.plugins.circuit.Gate)
     */
    public void signalHasBeenReceived(CircuitGate sourceGate) {
        if (sourceGate != null){

            // The source gate is an input
            sourceGate.setInput(true);

            CircuitGate targetGate = getTargetGate(sourceGate);
            if (targetGate != null){

                //  The source gate is an output
                targetGate.setInput(false);

                // Forward signal to target gate
                targetGate.sendSignal(sourceGate.getCurrentSignal(), sourceGate.getCurrentSignalEventId());
            }
        }
    }

    /**
     * Get the gate on which the incoming signal shall be propagated, according to the source gate
     * Return null if there is no target gate for this source gate.
     * @param sourceGate
     * @return <b>(Gate)</b>  A Gate. The gate gate
     */
    protected abstract CircuitGate getTargetGate(CircuitGate sourceGate);

    protected abstract SwitchInnerConnection cloneSwitchConnection(SwitchInnerConnection sc) throws InvalidSwitchConnection;
   

    /**
     *  Switch Inner Connection
     * A switch is composed of 8 inner connectors:
     * <br><br>
     *    C2 C3 C4<br>
     *   C1   []   C5<br>
     *    C8 C7 C6<br>
     * <br><br>  
     * The inner connection is either a line or an arc
     * <ul>
     <li>If the end connector index -   start connector index = 4, a line is created
     *  <li>If the end connector index -   start connector index = 2, an arc is created
     *  <li>Otherwise a exception is thrown
     * </ul>
     *   
     * @author zxpletran007
     */
    public abstract class SwitchInnerConnection {

        protected ColoredSignal connectionSignal = null;

        protected abstract Shape getShape();

        protected abstract void translate(int dx, int dy);

        protected abstract void resize(int dx, int dy);

        protected abstract void updateConnector();
       
        public void draw(Graphics2D g){
            Shape s = getShape();
            if (s != null){
                Color oldColor = g.getColor();
                g.setColor(connectionSignal!= null? connectionSignal.getColor() : drawColor);
                g.draw(s);
                g.setColor(oldColor);
            }
        }
    }

    public static class InvalidSwitchConnection extends Exception{
        public InvalidSwitchConnection(String arg0) {
            super(arg0);
        }    
    }

    public static class SwitchShapePropertiesNames extends Abstract2DShapePropertiesNames {
        private static transient String[] props = new String[] {
            "SWITCH_POSITION_SOURCE"
        };

        public SwitchShapePropertiesNames() {
            super();
            for (int i = 0; i < props.length; i++) {
                propertyNames.add(props[i]);
            }
        }
    }
   
   
    public String[] getPropertyNames() {
        if (_propertyNames == null) {
            _propertyNames = new SwitchShapePropertiesNames().getPropertyNames();
        }
        return _propertyNames;
    }

    public Object getPropertyValue(String name) {
        Object res = super.getPropertyValue(name);
       
        if (name.equalsIgnoreCase("SWITCH_POSITION_SOURCE")) {
            res = switchPositionDs;
        }
       
        return res;
    }

    /*
     * (non-Javadoc)
     *
     * @see simtools.shapes.AbstractShape#setProperty(java.lang.String,
     *      java.lang.Object)
     */
    public void setPropertyValue(String name, Object value) {
        super.setPropertyValue(name, value);
        if (name.equalsIgnoreCase("SWITCH_POSITION_SOURCE")) {
            setSwitchPositionDs( (DataSource)value);
            updateSwitch();
        }
    }

    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#getPanel(java.util.List)
     */
    public JPropertiesPanel getPanel(List properties) {
        if (properties == null){
            return null;
        }

        if (properties.containsAll(Arrays.asList(new SwitchShapePropertiesNames().getPropertyNames()))){
            return new SwitchShapePropertiesPanel(CircuitPlugin.resources.getString("Switch"));

        } else {
            return super.getPanel(properties);
        }
    }

   
   
    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.base.DataSourceConsumer#canAddDataSource(simtools.data.DataSource)
     */
    public boolean canAddDataSource(DataSource d) {
        return true;
    }

    public boolean doAction(double x, double y, Object o, String action, CompoundEdit undoableEdit) {
        boolean res;

        if (action.equals(CircuitPlugin.resources.getString("setSource"))) {
            // Save old params
            CompoundEdit ce = new CompoundEdit();
            HashMap oldValues = new HashMap();
            oldValues.put("SWITCH_POSITION_SOURCE", switchPositionDs);

            addDataSource((DataSource)o);

            // Notify changes
            Iterator it = oldValues.keySet().iterator();
            while (it.hasNext()) {
                String n = (String) it.next();
                ce.addEdit(new PropertyChangeEdit(this, n, oldValues.get(n), getPropertyValue(n)));
            }
            ce.end();
            if (undoableEdit != null) {
                undoableEdit.addEdit(ce);
            }

            res =  true;

        } else {
            res = super.doAction(x,y,o,action, undoableEdit);
        }

        return res;
    }




    public String[] getActions(double x, double y, Object o, int context) {
        if (context == MOUSE_OVER_CONTEXT) {
            return null;
        }
        if (context == MOUSE_OUT_CONTEXT) {
            return null;
        }
        if (context == MOUSE_PRESSED_CONTEXT) {
            return null;
        }

        ArrayList v = new ArrayList();

        if ( (context == EDITOR_CONTEXT) && (o instanceof DataSource)){
            v.add(CircuitPlugin.resources.getString("setSource"));
        }
        return (String[])v.toArray(new String[v.size()]);
    }


}
TOP

Related Classes of jsynoptic.plugins.circuit.switches.Switch$SwitchShapePropertiesNames

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.