blue.automation.Parameter.java Source code

Java tutorial

Introduction

Here is the source code for blue.automation.Parameter.java

Source

/*
 * blue - object composition environment for csound
 * Copyright (c) 2000-2006 Steven Yi (stevenyi@gmail.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by  the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307 USA
 */

package blue.automation;

import blue.components.lines.Line;
import blue.components.lines.LinePoint;
import blue.components.lines.LineUtils;
import electric.xml.Element;
import electric.xml.Elements;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.rmi.dgc.VMID;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * Data class to describe an automatable parameter's properties. This class
 * should holds boundary information (min and max) as well as allows for
 * listeners to follow changes to parameter information. A default value is also
 * necessary.
 * 
 * @author steven
 */
public class Parameter implements TableModelListener, Serializable {

    private float min = 0.0f;

    private float max = 1.0f;

    private float value = 0.0f;

    private String name = "";

    private String label = "";

    private float resolution = -1.0f;

    private Line line;

    transient Vector listeners;

    private boolean automationEnabled = false;

    private boolean updatingLine = false;

    private String uniqueId;

    /* Used only at compilation time */
    private String compilationVarName = null;

    /** Creates a new instance of Parameter */
    public Parameter() {
        line = new Line(false);
        line.addTableModelListener(this);

        uniqueId = Integer.toString(new VMID().hashCode());
    }

    /* Change Listener Code */

    public void addParameterListener(ParameterListener listener) {
        if (listeners == null) {
            listeners = new Vector();
        }
        listeners.add(listener);
    }

    public void removeParameterListener(ParameterListener listener) {
        if (listeners != null) {
            listeners.remove(listener);
        }
    }

    private void fireParameterChanged() {
        if (listeners == null) {
            return;
        }

        Iterator iter = new Vector(listeners).iterator();
        while (iter.hasNext()) {
            ParameterListener cl = (ParameterListener) iter.next();
            cl.parameterChanged(this);
        }
    }

    private void fireLineDataChanged() {
        if (listeners == null) {
            return;
        }

        Iterator iter = new Vector(listeners).iterator();
        while (iter.hasNext()) {
            ParameterListener cl = (ParameterListener) iter.next();
            cl.lineDataChanged(this);
        }
    }

    public void fireUpdateFromTimeChange() {
        fireLineDataChanged();
    }

    /* GETTER/SETTER CODE */

    public float getMin() {
        return min;
    }

    public float getMax() {
        return max;
    }

    public void setMin(float min, boolean truncate) {
        float oldMin = this.min;
        this.min = min;

        updatingLine = true;
        line.setMin(min, truncate);

        if (truncate) {
            value = LineUtils.truncate(value, this.min, this.max);
        } else {
            value = LineUtils.rescale(value, oldMin, this.max, this.min, this.max, this.resolution);
        }

        updatingLine = false;

        fireParameterChanged();
    }

    public void setMax(float max, boolean truncate) {
        float oldMax = this.max;
        this.max = max;

        updatingLine = true;
        line.setMax(max, truncate);

        if (truncate) {
            value = LineUtils.truncate(value, this.min, this.max);
        } else {
            value = LineUtils.rescale(value, this.min, oldMax, this.min, this.max, this.resolution);
        }

        updatingLine = false;

        fireParameterChanged();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;

        fireParameterChanged();
    }

    public float getResolution() {
        return resolution;
    }

    public void setResolution(float resolution) {
        // if(this.resolution == resolution) {
        // return;
        // }

        this.resolution = resolution;

        this.line.setResolution(resolution);
    }

    public Line getLine() {
        return line;
    }

    public void setLine(Line line) {
        this.line = line;
    }

    public String getUniqueId() {
        return uniqueId;
    }

    /* Listening to Line Value Changes to fire events to update UI */

    public void tableChanged(TableModelEvent e) {
        if (!updatingLine) {
            fireLineDataChanged();
        }
    }

    public void setValue(float value) {

        if (isAutomationEnabled()) {

            float time = ParameterTimeManagerFactory.getInstance().getTime();

            if (time < 0) {
                return;
            }

            updatingLine = true;
            LinePoint found = null;
            for (int i = 0; i < line.size(); i++) {
                LinePoint point = line.getLinePoint(i);
                if (point.getX() == time) {
                    found = point;
                    break;
                }

            }

            if (found != null) {
                found.setLocation(found.getX(), value);
            } else {
                LinePoint lp = new LinePoint();
                lp.setLocation(time, value);
                line.insertLinePoint(lp);
            }

            updatingLine = false;
        } else {

            this.value = value;

            if (line.size() == 1) {
                updatingLine = true;

                LinePoint lp = line.getLinePoint(0);
                lp.setLocation(lp.getX(), value);

                updatingLine = false;
            }
        }

    }

    public float getValue(float time) {
        float retValue;

        if (isAutomationEnabled()) {

            retValue = line.getValue(time);

            if (resolution > 0 && time < line.getLinePoint(line.size() - 1).getX()) {
                retValue = getResolutionAdjustedValue(retValue);
            }
        } else {
            retValue = this.value; // line.getLinePoint(0).getY();
        }

        return retValue;
    }

    public float getFixedValue() {
        return this.value;
    }

    public float getResolutionAdjustedValue(float val) {
        if (val == max) {
            return max;
        }

        float valTarget = val - min;
        float temp = 0.0f;

        while (temp <= valTarget) {
            temp += resolution;
        }
        temp -= resolution;

        return temp + min;
    }

    public boolean isAutomationEnabled() {
        return automationEnabled;
    }

    public void setAutomationEnabled(boolean automationEnabled) {
        this.automationEnabled = automationEnabled;
    }

    /* SERIALIZATION CODE */

    public Element saveAsXML() {
        Element retVal = new Element("parameter");

        retVal.setAttribute("uniqueId", uniqueId);
        retVal.setAttribute("name", name);
        retVal.setAttribute("label", label);
        retVal.setAttribute("min", Float.toString(min));
        retVal.setAttribute("max", Float.toString(max));
        retVal.setAttribute("resolution", Float.toString(resolution));
        retVal.setAttribute("automationEnabled", Boolean.toString(automationEnabled));
        retVal.setAttribute("value", Float.toString(value));

        retVal.addElement(line.saveAsXML());

        return retVal;
    }

    public static Parameter loadFromXML(Element data) {
        Parameter retVal = new Parameter();

        String val = data.getAttributeValue("uniqueId");
        if (val != null && val.length() > 0) {
            retVal.uniqueId = val;
        }

        val = data.getAttributeValue("name");
        if (val != null && val.length() > 0) {
            retVal.name = val;
        }

        val = data.getAttributeValue("label");
        if (val != null && val.length() > 0) {
            retVal.label = val;
        }

        val = data.getAttributeValue("min");
        if (val != null && val.length() > 0) {
            retVal.min = Float.parseFloat(val);
        }

        val = data.getAttributeValue("max");
        if (val != null && val.length() > 0) {
            retVal.max = Float.parseFloat(val);
        }

        val = data.getAttributeValue("resolution");
        if (val != null && val.length() > 0) {
            retVal.resolution = Float.parseFloat(val);
        }

        val = data.getAttributeValue("automationEnabled");
        if (val != null && val.length() > 0) {
            retVal.automationEnabled = Boolean.valueOf(val).booleanValue();
        }

        Elements nodes = data.getElements();
        while (nodes.hasMoreElements()) {

            Element node = nodes.next();
            String nodeName = node.getName();

            if (nodeName.equals("line")) {
                retVal.line = Line.loadFromXML(node);
                retVal.line.addTableModelListener(retVal);
            }

        }

        /*
         * For checking of older projects where line did not have resolution
         * property (0.111.0)
         */
        if (retVal.line.getResolution() != retVal.getResolution()) {
            retVal.line.setResolution(retVal.getResolution());
        }

        /*
         * Seeting Value property from first line point, introduced in 0.124.0
         */

        val = data.getAttributeValue("value");
        if (val != null && val.length() > 0) {
            retVal.value = Float.parseFloat(val);
        }

        return retVal;
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof Parameter)) {
            return false;
        }

        Parameter other = (Parameter) obj;

        return new EqualsBuilder().append(uniqueId, other.uniqueId).append(min, other.min).append(max, other.max)
                .append(label, other.label).append(resolution, other.resolution).append(line, other.line)
                .append(automationEnabled, other.automationEnabled).append(updatingLine, other.updatingLine)
                .append(value, other.value).isEquals();

    }

    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    /*
     * This gets called as part of Serialization by Java and will do default
     * serialization plus reconnect the parameter as a listener to the Line
     */
    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
        stream.defaultReadObject();

        line.addTableModelListener(this);
    }

    public String getCompilationVarName() {
        return compilationVarName;
    }

    public void setCompilationVarName(String compilationVarName) {
        this.compilationVarName = compilationVarName;
    }
}