Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,15 @@ public class AdjustmentCurveInstance extends AbstractRuntimeComponentInstance {
final int MODE_CLIPMINMAX = 0;
final int MODE_AUTOMINMAX = 1;

static final int OPMODE_FROM_FILE = 0;
static final int OPMODE_FROM_PROP_PERCENT = 1;
static final int OPMODE_FROM_PROP_ABSOLUTE = 2;

final int MAX_REDRAWSPEED = 50;

private double input = 500;
private double output = 500;
private int active = 0;
private boolean guiVisible = false;

public Vector<CurvePoint> curvePoints = new Vector<CurvePoint>();

Expand All @@ -81,6 +85,8 @@ public class AdjustmentCurveInstance extends AbstractRuntimeComponentInstance {
public int propFontSize = 14;
public String propCaption = "dotMeter";
public String propFilename = "curve1";
public int propOperationMode = 0;
String propCurvePoints;

long timestamp = 0;

Expand All @@ -99,7 +105,6 @@ public AdjustmentCurveInstance() {
* CurvePoint e= new CurvePoint(); e.x=0; e.y=0; curvePoints.add(e); e=
* new CurvePoint(); e.x=1000; e.y=1000; curvePoints.add(e);
*/

}

public synchronized void load() {
Expand Down Expand Up @@ -131,6 +136,27 @@ public synchronized void load() {
e.printStackTrace();
}
}

private void loadFromProperty() {
curvePoints.clear();
try {
if (propCurvePoints != null && !"".equals(propCurvePoints)) {
propCurvePoints = propCurvePoints.replace(" ", "");
String[] stringPoints = propCurvePoints.split("\\),");
for (String stringPoint : stringPoints) {
stringPoint = stringPoint.replace(")", "").replace("(", "");
String[] stringValues = stringPoint.split(",");
CurvePoint c = new CurvePoint();
c.x = Double.parseDouble(stringValues[0]);
c.y = Double.parseDouble(stringValues[1]);
curvePoints.add(c);
}
}
} catch (Exception e) {
AstericsErrorHandling.instance.reportError(this,
"AdjustmentCurve: Could not parse 'propCurvePoints'. Make sure the format is like '(1,2),(2,3),(4,5)'.");
}
}

public synchronized void save() {
FileOutputStream fOut = null;
Expand Down Expand Up @@ -161,30 +187,52 @@ public double calculateOutputValue(double x) {
CurvePoint a, b;

if (curvePoints.size() > 1) {
a = curvePoints.get(0);
if (x <= a.x) {
return (a.y);
if (x <= getX(0)) {
return (getY(0));
}
b = curvePoints.get(curvePoints.size() - 1);
if (x >= b.x) {
return (b.y);
if (x >= getX(curvePoints.size() - 1)) {
return (getY(curvePoints.size() - 1));
}
int i = 0;
while ((i < curvePoints.size() - 1) && (x > curvePoints.get(i).x)) {
while ((i < curvePoints.size() - 1) && (x > getX(i))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments would be nice:
You are looking for the first point, where x > curvePoint.x(i)??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, looks like that this is what the code is doing... ;)
It's just the old logic where the x/y values now aren't directly retrieved form curvePoints, but using helper methods getX() and getY() for making a mode possible where the points are interpreted as percentage values. I'm sure the logic could be somehow improved/beautified but since there are no automatic tests I thought I'll better leave it as it is. However I did some manual tests with the test models existing for AdjustmentCurve and they worked the same way as before after my changes.

i++;
}

a = curvePoints.get(i - 1);
b = curvePoints.get(i);
double ax = getX(i - 1);
double ay = getY(i - 1);
double bx = getX(i);
double by = getY(i);
// System.out.println("x="+x+", a.x="+a.x+",b.x="+b.x);

double f = (x - a.x) / (b.x - a.x);
return (a.y + (b.y - a.y) * f);
double f = (x - ax) / (bx - ax);
return (ay + (by - ay) * f);
} else {
return (0);
}
}

private double getX(int index) {
double value = curvePoints.get(index).x;
if(propOperationMode == OPMODE_FROM_PROP_PERCENT) {
value = value > 100 ? 100 : value;
value = value < 0 ? 0 : value;
double range = propInMax - propInMin;
value = (value * range / 100) + propInMin;
}
return value;
}

private double getY(int index) {
double value = curvePoints.get(index).y;
if(propOperationMode == OPMODE_FROM_PROP_PERCENT) {
value = value > 100 ? 100 : value;
value = value < 0 ? 0 : value;
double range = propOutMax - propOutMin;
value = (value * range / 100) + propOutMin;
}
return value;
}

/**
* returns an Input Port.
*
Expand Down Expand Up @@ -248,12 +296,18 @@ public Object getRuntimePropertyValue(String propertyName) {
if ("mode".equalsIgnoreCase(propertyName)) {
return propMode;
}
if ("operationMode".equalsIgnoreCase(propertyName)) {
return propOperationMode;
}
if ("fontSize".equalsIgnoreCase(propertyName)) {
return propFontSize;
}
if ("caption".equalsIgnoreCase(propertyName)) {
return propCaption;
}
if ("curvePoints".equalsIgnoreCase(propertyName)) {
return propCurvePoints;
}
return null;
}

Expand Down Expand Up @@ -300,16 +354,12 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) {
if ("true".equalsIgnoreCase((String) newValue)) {
propDisplayGui = true;
if (oldValue == false) {
gui = new GUI(this, AREServices.instance.getAvailableSpace(this));
AREServices.instance.displayPanel(gui, this, true);
gui.updateGraph(input, output);
active = 1;
showGui();
}
} else if ("false".equalsIgnoreCase((String) newValue)) {
propDisplayGui = false;
if ((oldValue == true) && (gui != null)) {
AREServices.instance.displayPanel(gui, this, false);
active = 0;
if (oldValue == true) {
hideGui();
}
}
return oldValue;
Expand Down Expand Up @@ -354,7 +404,29 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) {
}
return oldValue;
}

if ("operationMode".equalsIgnoreCase(propertyName)) {
final int oldValue = propOperationMode;
propOperationMode = Integer.parseInt(newValue.toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in theory newValue could be null.

But this would also be a problem for the other properties

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question as in #294 (comment)

if (oldValue != propOperationMode) {
switch (propOperationMode) {
case OPMODE_FROM_FILE:
load();
if (propDisplayGui) {
showGui();
}
break;
case OPMODE_FROM_PROP_PERCENT:
loadFromProperty();
hideGui();
break;
case OPMODE_FROM_PROP_ABSOLUTE:
loadFromProperty();
hideGui();
break;
}
}
return oldValue;
}
if ("fontSize".equalsIgnoreCase(propertyName)) {
final Object oldValue = propFontSize;
propFontSize = Integer.parseInt(newValue.toString());
Expand All @@ -365,6 +437,14 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) {
propCaption = newValue.toString();
return oldValue;
}
if ("curvePoints".equalsIgnoreCase(propertyName)) {
final Object oldValue = propCurvePoints;
propCurvePoints = newValue.toString();
if(propOperationMode == OPMODE_FROM_PROP_ABSOLUTE || propOperationMode == OPMODE_FROM_PROP_PERCENT) {
loadFromProperty();
}
return oldValue;
}
return null;
}

Expand All @@ -376,7 +456,7 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) {
public void receiveData(byte[] data) {
input = ConversionUtils.doubleFromBytes(data);
output = calculateOutputValue(input);
if ((propDisplayGui == true) && (active == 1)) {
if ((propDisplayGui == true) && guiVisible) {
if (System.currentTimeMillis() - timestamp > MAX_REDRAWSPEED) {
gui.updateGraph(input, output);
timestamp = System.currentTimeMillis();
Expand Down Expand Up @@ -405,32 +485,25 @@ public void receiveData(byte[] data) {
final IRuntimeEventListenerPort elpDisplayGui = new IRuntimeEventListenerPort() {
@Override
public void receiveEvent(final String data) {

if (propDisplayGui == false) {
propDisplayGui = true;
gui = new GUI(thisInstance, AREServices.instance.getAvailableSpace(thisInstance));
AREServices.instance.displayPanel(gui, thisInstance, true);
gui.updateGraph(input, output);
active = 1;
showGui();
}
}
};
final IRuntimeEventListenerPort elpHideGui = new IRuntimeEventListenerPort() {
@Override
public void receiveEvent(final String data) {
propDisplayGui = false;
if (gui != null) {
AREServices.instance.displayPanel(gui, thisInstance, false);
}
active = 0;
hideGui();
// gui.updateGraph(input,output);
}
};
final IRuntimeEventListenerPort elpLoadCurve = new IRuntimeEventListenerPort() {
@Override
public void receiveEvent(final String data) {
// System.out.println("Load Curve");
// if (active==0)
// if (guiVisible)
load();
}
};
Expand All @@ -452,11 +525,8 @@ public void start() {
output = calculateOutputValue(input);

if (propDisplayGui == true) {
gui = new GUI(this, AREServices.instance.getAvailableSpace(this));
AREServices.instance.displayPanel(gui, this, true);
gui.updateGraph(input, output);
showGui();
}
active = 1;
super.start();
}

Expand All @@ -481,9 +551,24 @@ public void resume() {
*/
@Override
public void stop() {
AREServices.instance.displayPanel(gui, this, false);

active = 0;
hideGui();
super.stop();
}

private void showGui() {
if(propOperationMode != OPMODE_FROM_FILE || guiVisible) {
return;
}
gui = new GUI(this, AREServices.instance.getAvailableSpace(this));
AREServices.instance.displayPanel(gui, this, true);
gui.updateGraph(input, output);
guiVisible = true;
}

private void hideGui() {
if (gui != null) {
AREServices.instance.displayPanel(gui, this, false);
guiVisible = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,24 @@
type="integer"
value="1"
combobox="clip to min and max//autoupdate min and max"
description="how to deal with input values exceeding min or max"/>
description="how to deal with input values exceeding min or max (GUI related only)"/>
<property name="fontSize"
type="integer"
value="14"
description="font size of dotmeter captions"/>
<property name="caption"
type="string"
value="signal mapper"
description="caption of the curve window"/>
description="caption of the curve window"/>
<property name="operationMode"
type="integer"
value="0"
combobox="use file and GUI//use property curvePoints (percent values)//use property curvePoints (absolute values)"
description="operation mode, either use file and GUI or property curvePoints"/>
<property name="curvePoints"
type="string"
value="(10,0),(10,10),(100,100)"
description="curvePoints (x/y) for operationMode 'curve points from property'"/>
</properties>
<gui>
<width>5000</width>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,18 @@ <H2>Properties</H2>
<li><STRONG>outMax [double]:</STRONG> Sets the maximum value of the input range.</li>
<li><STRONG>outMin [double]:</STRONG> Sets the minimum value of the output range.</li>
<li><STRONG>outMax [double]:</STRONG> Sets the maximum value of the output range.</li>
<li><STRONG>mode [combobox]:</STRONG> "autoupdate min and max" modifies the input range if incoming values exceed the current minimum or maximum, "clip to min and max" which keeps the values as set by the min/max properties.</li>
<li><STRONG>mode [combobox]:</STRONG> GUI mode: "autoupdate min and max" modifies the shown input range of the GUI if incoming values exceed the current minimum or maximum, "clip to min and max" which keeps the values as set by the min/max properties.</li>
<li><STRONG>fontSize [integer]:</STRONG> The size of the font for dispaying text in the GUI.</li>
<li><STRONG>caption [string]:</STRONG> The caption of the AdjustmentCurve GUI.</li>
<li>
<STRONG>operationMode [integer]:</STRONG> Selects the mode of operation of the adjustment curve component, following modes are available:
<ul>
<li><EM>"use file and GUI":</EM> Default mode. The x/y points of the adjustment curve are defined using the graphical user interface and are stored and loaded from a file, defined by property 'filename'.</li>
<li><EM>"use property curvePoints (percent values)":</EM> No GUI is shown, x/y points of the adjustmentcurve are defined by property 'curvePoints' and interpreted as relative percentatge values of given in/out min/max values. In this mode no external file is needed or used. </li>
<li><EM>"use property curvePoints (absolute values)":</EM> Same mode as before, using property 'curvePoints' with the difference that x/y values are defined as absolute values.</li>
</ul>
</li>
<li><STRONG>curvePoints [string]:</STRONG> For operation mode 'use property curvePoints' this property defines the x/y points of the adjustment curve. The expected format are comma-separated tuples of double or integer values like e.g. '(10.0,0.0),(10,10),(100,100)' defining 3 x/y points.</li>
</ul>
</BODY>
</HTML>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.