Commit 96acfb10 authored by moll's avatar moll
Browse files

Adaptions to tulip-cps 1.4.0; trigger sound not in paint

parent df185030
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
<dependency> <dependency>
<groupId>lu.list.itis.dkd.tui</groupId> <groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip</artifactId> <artifactId>tulip</artifactId>
<version>2.3.1</version> <version>2.4.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>lu.list.itis.dkd.tui</groupId> <groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip-cps</artifactId> <artifactId>tulip-cps</artifactId>
<version>1.3.1</version> <version>1.4.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -31,8 +31,9 @@ bootstrapping.root = circuit_scenario.xml ...@@ -31,8 +31,9 @@ bootstrapping.root = circuit_scenario.xml
# Properties for the equation system # Properties for the equation system
scriptEngine.executable = C:/Octave/Octave-3.8.2/bin/octave.exe executor.class = lu.list.itis.dkd.tui.cps.system.executor.JavascriptExecutor
scriptEngine.workingDir = model numeric.variable.class = lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable
equation.system = circuit_scenario.xml equation.system = circuit_scenario.xml
scenario.description = circuit_scenario.xml scenario.description = circuit_scenario.xml
......
# Properties for the Logger
logger.event.output.location = log.txt # Properties for the Logger
logger.event.output.enabled = false logger.event.output.location = log.txt
logger.level = ALL logger.event.output.enabled = false
logger.event.configuration = logger.xml logger.level = ALL
logger.event.configuration = logger.xml
# Widget IDs to be mapped
# Widget IDs to be mapped
# Properties for calibrating the interface
frameTitle = NUI Application # Properties for calibrating the interface
windowWidth = 1920 frameTitle = NUI Application
windowHeight = 1080 windowWidth = 1920
fullScreen = false windowHeight = 1080
font = Arial fullScreen = false
fontSize = 13 font = Arial
colour = BLACK fontSize = 13
centred = false colour = BLACK
centred = false
# Properties for the calibration of the object manager
#The value below is best left at or above 1024 # Properties for the calibration of the object manager
cursor.id.remapping.constant = 1024 #The value below is best left at or above 1024
cursor.id.remapping.constant = 1024
# The low-level computer vision (or similar) adapter to load.
# Syntax is : adapter.class = packageName.ClassName # The low-level computer vision (or similar) adapter to load.
adapter.class = lu.list.itis.dkd.tui.adapter.TuioAdapter # Syntax is : adapter.class = packageName.ClassName
adapter.class = lu.list.itis.dkd.tui.adapter.TuioAdapter
# The location and name of the root bootstrapping file.
bootstrapping.root = light_scenario.xml # The location and name of the root bootstrapping file.
bootstrapping.root = light_scenario.xml
# Properties for the equation system
#scriptEngine.executable = C:/Octave/Octave-3.8.2/bin/octave.exe # Properties for the equation system
#scriptEngine.workingDir = model executor.class = lu.list.itis.dkd.tui.cps.system.executor.JavascriptExecutor
executor.class=lu.list.itis.dkd.tui.cps.system.executor.JavascriptExecutor numeric.variable.class = lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable
variable.class=lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable logic.variable.class = lu.list.itis.dkd.tui.cps.variable.BooleanVariable
equation.system = light_scenario.xml
scenario.description = light_scenario.xml
/**
* Copyright Luxembourg Institute of Science and Technology, 2016. /**
* * Copyright Luxembourg Institute of Science and Technology, 2016.
* This file is part of TULIP. *
* * This file is part of TULIP.
* TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3, *
* as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST * TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3,
* proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license. * as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST
* * proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license.
* For all non-commercial purposes, TULIP 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 * For all non-commercial purposes, TULIP is free software; you can redistribute it and/or modify it
* Foundation, version 3 of the License. * under the terms of the GNU Lesser General Public License as published by the Free Software
* * Foundation, version 3 of the License.
* TULIP 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 * TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* General Public License for more details. * 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 TULIP. If *
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>. * You should have received a copy of the GNU Lesser General Public License along with TULIP. If
*/ * not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
package lu.list.itis.dkd.tui.scenario; */
package lu.list.itis.dkd.tui.scenario;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable; import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.TangibleApplication; import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.TangibleObjectManager; import lu.list.itis.dkd.tui.TangibleApplication;
import lu.list.itis.dkd.tui.bootstrapping.TangibleApplicationBootstrapper; import lu.list.itis.dkd.tui.TangibleObjectManager;
import lu.list.itis.dkd.tui.cps.system.EquationSystemBuilder; import lu.list.itis.dkd.tui.bootstrapping.TangibleApplicationBootstrapper;
import lu.list.itis.dkd.tui.cps.system.EquationSystemException; import lu.list.itis.dkd.tui.cps.system.EquationSystemBuilder;
import lu.list.itis.dkd.tui.cps.variable.Variable; import lu.list.itis.dkd.tui.cps.system.EquationSystemException;
import lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable; import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.exception.BuildException; import lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable;
import lu.list.itis.dkd.tui.scenario.bootstrapping.SceneBootstrapper; import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.PropertiesFetcher; import lu.list.itis.dkd.tui.scenario.bootstrapping.SceneBootstrapper;
import lu.list.itis.dkd.tui.widget.BaseWidget; import lu.list.itis.dkd.tui.utility.PropertiesFetcher;
import lu.list.itis.dkd.tui.widget.ValueWidget; import lu.list.itis.dkd.tui.widget.BaseWidget;
import lu.list.itis.dkd.tui.widget.corona.ConditionalCorona; import lu.list.itis.dkd.tui.widget.ValueWidget;
import lu.list.itis.dkd.tui.widget.corona.ConditionalCorona;
import com.google.common.base.Preconditions;
import com.google.common.base.Preconditions;
import java.io.File;
import java.util.Map; import java.io.File;
import java.util.Properties; import java.util.Map;
import java.util.Properties;
/**
* Class used to run a tangible scenario. It uses bootstrappers to initialize all the necessary /**
* components from an XML file. * Class used to run a tangible scenario. It uses bootstrappers to initialize all the necessary
* * components from an XML file.
* @author Eric Tobias [eric.tobias@list.lu] *
* @since 1.0 * @author Eric Tobias [eric.tobias@list.lu]
* @version 1.1.2 * @since 1.0
*/ * @version 1.1.2
@NonNullByDefault */
public class Scenario { @NonNullByDefault
private Map<String, Scene> scenes; public class Scenario {
private Map<String, Scene> scenes;
private static Map<String, Variable> inputs;
private static Map<String, Variable> outputs; private static Map<String, Variable> inputs;
private EquationSystemBuilder equationSystemBuilder; private static Map<String, Variable> outputs;
private EquationSystemBuilder equationSystemBuilder;
Properties properties;
private TangibleApplication tangibleApplication; Properties properties;
private TangibleApplication tangibleApplication;
/**
* Constructor initializing all fields. The constructor will also populate all variables and use /**
* a bootstrapper to initialize a {@link TangibleApplication} and a {@link StageManager} to * Constructor initializing all fields. The constructor will also populate all variables and use
* manage all scenes reacting to inputs and outputs. * a bootstrapper to initialize a {@link TangibleApplication} and a {@link StageManager} to
* * manage all scenes reacting to inputs and outputs.
* @throws BuildException *
* thrown when the provided URI could not be interpreted and, hence, the scenario * @throws BuildException
* description document loaded. * thrown when the provided URI could not be interpreted and, hence, the scenario
*/ * description document loaded.
public Scenario(String file) throws BuildException { */
properties = PropertiesFetcher.fetchProperties(file); public Scenario(String file) throws BuildException {
try { try {
equationSystemBuilder = new EquationSystemBuilder(properties); properties = PropertiesFetcher.fetchProperties(file);
equationSystemBuilder.parseEquationFile(new File(properties.getProperty("equation.system"))); //$NON-NLS-1$ equationSystemBuilder = new EquationSystemBuilder(properties);
} catch (final EquationSystemException exception) { equationSystemBuilder.parseEquationFile(new File(properties.getProperty("equation.system"))); //$NON-NLS-1$
throw new BuildException("The equation system for this scenario could not be built!", exception); //$NON-NLS-1$ } catch (final EquationSystemException exception) {
} throw new BuildException("The equation system for this scenario could not be built!", exception); //$NON-NLS-1$
}
inputs = equationSystemBuilder.getInputVariables();
outputs = equationSystemBuilder.getOutputVariables(); inputs = equationSystemBuilder.getInputVariables();
outputs = equationSystemBuilder.getOutputVariables();
tangibleApplication = new TangibleApplicationBootstrapper(file);
tangibleApplication = new TangibleApplicationBootstrapper(file);
populateVariables();
populateVariables();
scenes = SceneBootstrapper.getScenes();
StageManager.setScenes(scenes); scenes = SceneBootstrapper.getScenes();
tangibleApplication.setContentManager(StageManager.getInstance()); StageManager.setScenes(scenes);
tangibleApplication.setContentManager(StageManager.getInstance());
tangibleApplication.connect();
} tangibleApplication.connect();
}
public Scenario(String file, String filename) throws BuildException {
public Scenario(String file, String filename) throws BuildException {
properties = PropertiesFetcher.fetchProperties(file);
properties.setProperty("equation.system", filename); //$NON-NLS-1$ properties = PropertiesFetcher.fetchProperties(file);
properties.setProperty("bootstrapping.root", filename); //$NON-NLS-1$ properties.setProperty("equation.system", filename); //$NON-NLS-1$
properties.setProperty("scenario.description", filename); //$NON-NLS-1$ properties.setProperty("bootstrapping.root", filename); //$NON-NLS-1$
properties.setProperty("scenario.description", filename); //$NON-NLS-1$
try {
equationSystemBuilder = new EquationSystemBuilder(properties); try {
equationSystemBuilder.parseEquationFile(new File(properties.getProperty("equation.system"))); //$NON-NLS-1$ equationSystemBuilder = new EquationSystemBuilder(properties);
} catch (final EquationSystemException exception) { equationSystemBuilder.parseEquationFile(new File(properties.getProperty("equation.system"))); //$NON-NLS-1$
throw new BuildException("The equation system for this scenario could not be built!", exception); //$NON-NLS-1$ } catch (final EquationSystemException exception) {
} throw new BuildException("The equation system for this scenario could not be built!", exception); //$NON-NLS-1$
}
inputs = equationSystemBuilder.getInputVariables();
outputs = equationSystemBuilder.getOutputVariables(); inputs = equationSystemBuilder.getInputVariables();
outputs = equationSystemBuilder.getOutputVariables();
tangibleApplication = new TangibleApplicationBootstrapper(file);
tangibleApplication = new TangibleApplicationBootstrapper(file);
populateVariables();
populateVariables();
scenes = SceneBootstrapper.getScenes();
StageManager.setScenes(scenes); scenes = SceneBootstrapper.getScenes();
tangibleApplication.setContentManager(StageManager.getInstance()); StageManager.setScenes(scenes);
tangibleApplication.setContentManager(StageManager.getInstance());
tangibleApplication.connect();
} tangibleApplication.connect();
}
/**
* Method used to replace the placeholder variables in each widget with the variable as /**
* initialized by the equation system. The method will also set all trigger variables of * Method used to replace the placeholder variables in each widget with the variable as
* conditional corona with the variables for the given trigger names. * initialized by the equation system. The method will also set all trigger variables of
* * conditional corona with the variables for the given trigger names.
*/ *
private void populateVariables() { */
for (final BaseWidget widget : TangibleObjectManager.getWidgets()) { private void populateVariables() {
if (widget instanceof ValueWidget) { for (final BaseWidget widget : TangibleObjectManager.getWidgets()) {
final TangibleNumericalVariable variable = retrieveVariableByName(((ValueWidget) widget).getVariable().getName()); if (widget instanceof ValueWidget) {
((ValueWidget) widget).setVariable(variable); final TangibleNumericalVariable variable = retrieveVariableByName(((ValueWidget) widget).getVariable().getName());
((ValueWidget) widget).setVariable(variable);
for (final ConditionalCorona corona : widget.getCoronas(ConditionalCorona.class)) {
corona.getTriggers().forEach(trigger -> corona.addVariable(retrieveVariableByName(trigger))); for (final ConditionalCorona corona : widget.getCoronas(ConditionalCorona.class)) {
} corona.getTriggers().forEach(trigger -> corona.addVariable(retrieveVariableByName(trigger)));
} }
} }
} }
}
/**
* Method used to find a variable given its name in either input or output maps. /**
* * Method used to find a variable given its name in either input or output maps.
* @param name *
* The name of the variable to find. * @param name
* @return The {@link TangibleNumericalVariable} that responds to the given name or * The name of the variable to find.
* <code>null</code> should no such variable exist. * @return The {@link TangibleNumericalVariable} that responds to the given name or
*/ * <code>null</code> should no such variable exist.
static @Nullable TangibleNumericalVariable retrieveVariableByName(String name) { */
return (TangibleNumericalVariable) (inputs.get(name) == null ? outputs.get(name) : inputs.get(name)); static @Nullable TangibleNumericalVariable retrieveVariableByName(String name) {
} return (TangibleNumericalVariable) (inputs.get(name) == null ? outputs.get(name) : inputs.get(name));
}
/**
* Entry point for the application. /**
* * Entry point for the application.
* @param args *
* This must be empty, no arguments are accepted. * @param args
* @throws BuildException * This must be empty, no arguments are accepted.
*/ * @throws BuildException
public static void main(String[] args) throws BuildException { */
Preconditions.checkArgument(args.length == 1, "1 parameter needed"); //$NON-NLS-1$ public static void main(String[] args) throws BuildException {
@SuppressWarnings("unused") Preconditions.checkArgument(args.length == 1, "1 parameter needed"); //$NON-NLS-1$
final Scenario scenario = new Scenario(args[0]); @SuppressWarnings("unused")
} final Scenario scenario = new Scenario(args[0]);
}
} }
\ No newline at end of file
...@@ -26,6 +26,7 @@ import lu.list.itis.dkd.tui.TangibleContentManager; ...@@ -26,6 +26,7 @@ import lu.list.itis.dkd.tui.TangibleContentManager;
import lu.list.itis.dkd.tui.content.Content; import lu.list.itis.dkd.tui.content.Content;
import lu.list.itis.dkd.tui.cps.system.Equation; import lu.list.itis.dkd.tui.cps.system.Equation;
import lu.list.itis.dkd.tui.cps.system.Mapping; import lu.list.itis.dkd.tui.cps.system.Mapping;
import lu.list.itis.dkd.tui.cps.system.executor.JavascriptExecutor;
import lu.list.itis.dkd.tui.cps.variable.BooleanVariable; import lu.list.itis.dkd.tui.cps.variable.BooleanVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable; import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.exception.BuildException; import lu.list.itis.dkd.tui.exception.BuildException;
...@@ -77,6 +78,7 @@ public class Scene extends Content { ...@@ -77,6 +78,7 @@ public class Scene extends Content {
private boolean triggered = false; private boolean triggered = false;
private AudioInputStream audioIn; private AudioInputStream audioIn;
private AudioInputStream audioStream; private AudioInputStream audioStream;
private boolean isPlaying;
/** /**
* Constructor initializing all fields. * Constructor initializing all fields.
...@@ -110,10 +112,12 @@ public class Scene extends Content { ...@@ -110,10 +112,12 @@ public class Scene extends Content {
variables.add(triggerVariable); variables.add(triggerVariable);
} }
final LinkedHashSet<Variable> triggerVariables = new LinkedHashSet<Variable>();
// trigger = new Equation(new Mapping(variables, triggerVariable), triggerCondition); final LinkedHashSet<Variable> outputs = new LinkedHashSet<>();
triggerVariables.add(triggerVariable); outputs.add(triggerVariable);
trigger = new Equation(new Mapping(variables, triggerVariables), triggerCondition);
trigger = new Equation(new Mapping(variables, outputs), triggerCondition);
trigger.setExecutor(new JavascriptExecutor());
try { try {
final Element imageNode = element.getChild(Externalization.IMAGE_ELEMENT); final Element imageNode = element.getChild(Externalization.IMAGE_ELEMENT);
...@@ -132,7 +136,6 @@ public class Scene extends Content { ...@@ -132,7 +136,6 @@ public class Scene extends Content {
final Element imageBase64Node = element.getChild(Externalization.IMAGE_BASE64_ELEMENT); final Element imageBase64Node = element.getChild(Externalization.IMAGE_BASE64_ELEMENT);
if ((null != imageBase64Node) && (imageBase64Node.getText() != "")) { //$NON-NLS-1$ if ((null != imageBase64Node) && (imageBase64Node.getText() != "")) { //$NON-NLS-1$
final String[] tokens = (imageBase64Node.getText()).split(","); //$NON-NLS-1$ final String[] tokens = (imageBase64Node.getText()).split(","); //$NON-NLS-1$
// System.out.println(tokens[1]);
byte[] imageByte; byte[] imageByte;
imageByte = Base64.getDecoder().decode(tokens[1]); imageByte = Base64.getDecoder().decode(tokens[1]);
final ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); final ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
...@@ -170,9 +173,10 @@ public class Scene extends Content { ...@@ -170,9 +173,10 @@ public class Scene extends Content {
final Element soundBase64Node = element.getChild(Externalization.SOUND_BASE64_NODE); final Element soundBase64Node = element.getChild(Externalization.SOUND_BASE64_NODE);
if ((null != soundBase64Node) && (soundBase64Node.getText() != "")) { //$NON-NLS-1$ if ((null != soundBase64Node) && (soundBase64Node.getText() != "")) { //$NON-NLS-1$
final String[] tokens = (soundBase64Node.getText()).split(","); //$NON-NLS-1$ final String[] tokens = (soundBase64Node.getText()).split(","); //$NON-NLS-1$
// System.out.println(tokens[1]); final byte[] soundByte = Base64.getDecoder().decode(tokens[1]).clone();
final byte[] soundByte = Base64.getDecoder().decode(tokens[1]); final ByteArrayInputStream ais = new ByteArrayInputStream(soundByte);
audioIn = AudioSystem.getAudioInputStream(new ByteArrayInputStream(soundByte));
audioIn = AudioSystem.getAudioInputStream(ais);
audioClip = AudioSystem.getClip(); audioClip = AudioSystem.getClip();
audioClip.open(audioIn); audioClip.open(audioIn);
...@@ -211,26 +215,21 @@ public class Scene extends Content { ...@@ -211,26 +215,21 @@ public class Scene extends Content {
triggered = false; triggered = false;
} }
if (triggerVariable.getValue() && !triggered) {
playSound();
}
return triggerVariable.getValue(); return triggerVariable.getValue();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void paint(Graphics2D canvas) { public void paint(Graphics2D canvas) {
// canvas.drawImage(scenery, 0, 0, null);
if (scenery != null) { if (scenery != null) {
scenery.paintIcon(null, canvas, 0, 0); scenery.paintIcon(null, canvas, 0, 0);
} }
if ((!triggered) && (audioClip != null)) {
audioClip.setFramePosition(0);
audioClip.start();
triggered = true;
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void initialise() { public void initialise() {
...@@ -239,4 +238,21 @@ public class Scene extends Content { ...@@ -239,4 +238,21 @@ public class Scene extends Content {
/**
* @throws IOException
* @throws LineUnavailableException
*
*/
public void playSound() {
if (audioClip != null && !isPlaying && !triggered) {
triggered = true;
audioClip.setFramePosition(0);
audioClip.start();
// audioClip.drain();
// audioClip.loop(1);
}
}
} }
\ No newline at end of file
/**
* Copyright Luxembourg Institute of Science and Technology, 2016. /**
* * Copyright Luxembourg Institute of Science and Technology, 2016.
* This file is part of TULIP. *
* * This file is part of TULIP.
* TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3, *
* as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST * TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3,
* proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license. * as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST
* * proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license.
* For all non-commercial purposes, TULIP 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 * For all non-commercial purposes, TULIP is free software; you can redistribute it and/or modify it
* Foundation, version 3 of the License. * under the terms of the GNU Lesser General Public License as published by the Free Software
* * Foundation, version 3 of the License.
* TULIP 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 * TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* General Public License for more details. * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* * General Public License for more details.