Commit bc4b6269 authored by Eric Tobias's avatar Eric Tobias

2.1.3 - Added SpatialMatrixTest

+ Minor modification to some core classes to facilitate testing.
+ Moved property files to the config folder.
+ Added config folder as source folder.
parent 622c7a3f
......@@ -6,6 +6,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="config"/>
<classpathentry kind="src" output="target/test-classes" path="test">
<attributes>
<attribute name="optional" value="true"/>
......
# Properties for the Logger
logger.event.output.location = log.txt
logger.event.output.enabled = false
logger.level = ALL
logger.event.configuration = logger.xml
# Widget IDs to be mapped
# Properties for calibrating the interface
frameTitle = NUI Application
windowWidth = 1280
windowHeight = 800
fullScreen = false
font = Arial
fontSize = 13
colour = BLACK
centred = false
# Properties for the calibration of the object manager
#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
adapter.class = lu.list.itis.dkd.tui.adapter.TuioAdapter
\ No newline at end of file
#Tue May 12 16:02:47 CEST 2015
imerFreq=1000
frameTitle=NUI Application
zoomWidgetID=0
logger.event.configuration=logger.xml
fontSize=13
backgroundWidgetID=2
recenterWidgetID=23
logger.event.output.location=test_log.txt
calibrationFileURI=calibration.xml
infoWidgetID=1
windowHeight=800
colour=BLACK
fullScreen=false
zoomTimerFreq=1000
contentFileURI=contentLAMILO.xml
infoTimerFreq=600
centeredLuxembourg=false
font=Arial
splitWidgetID=22
logger.event.output.enabled=false
calibrationMode=false
legendScale=0.8
centred=false
windowWidth=1280
logger.level=FINE
cursor.id.remapping.constant=2048
# The low-level computer vision (or similar) adapter to load.
# Syntax is : adapter.class = packageName.ClassName
adapter.class = lu.list.itis.dkd.tui.adapter.TuioAdapter
\ No newline at end of file
......@@ -23,11 +23,10 @@ import lu.list.itis.dkd.tui.adapter.TuiAdapter;
import lu.list.itis.dkd.tui.logging.EventLogger;
import lu.list.itis.dkd.tui.utility.GlobalContext;
import lu.list.itis.dkd.tui.utility.IdMapper;
import lu.list.itis.dkd.tui.utility.PropertiesFetcher;
import com.google.common.base.Preconditions;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
......@@ -92,15 +91,17 @@ public abstract class TangibleApplication {
*/
protected TangibleApplication(@Nullable String newPropertiesFileURI) {
if (newPropertiesFileURI != null && !newPropertiesFileURI.isEmpty()) {
propertiesFileURI = newPropertiesFileURI;
properties = PropertiesFetcher.fetchProperties(newPropertiesFileURI);
}
try (FileInputStream inputStream = new FileInputStream(new File(propertiesFileURI))) {
properties.load(inputStream);
} catch (IOException ioe) {
logger.log(Level.SEVERE, "The properties file or values thereof could not be loaded!", ioe); //$NON-NLS-1$
System.exit(42);
}
properties = PropertiesFetcher.fetchProperties();
// try (FileInputStream inputStream = new FileInputStream(new File(propertiesFileURI))) {
// properties.load(inputStream);
// } catch (IOException ioe) {
// logger.log(Level.SEVERE, "The properties file or values thereof could not be loaded!",
// ioe); //$NON-NLS-1$
// System.exit(42);
// }
configureLogger(logger);
interfaceManager = new TangibleInterfaceManager(this, logger, properties);
......@@ -153,7 +154,7 @@ public abstract class TangibleApplication {
unconfiguredLogger.log(Level.SEVERE, "The logger could not be configured!", e); //$NON-NLS-1$
}
}
unconfiguredLogger.setLevel(Level.parse(properties.getProperty("logger.level"))); //$NON-NLS-1$
unconfiguredLogger.setLevel(Level.parse(properties.getProperty("logger.level", "ALL"))); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
......
......@@ -184,7 +184,13 @@ public abstract class TuiAdapter {
spatialEventListeners.remove(listener);
}
protected synchronized void notifyListeners(SpatialEvent event) {
/**
* Method used to notify all listeners of a given {@link SpatialEvent}.
*
* @param event
* The event to notify all listeners of.
*/
public synchronized void notifyListeners(SpatialEvent event) {
spatialEventListeners.forEach(listener -> listener.spaceUpdated(event));
}
}
\ No newline at end of file
......@@ -64,7 +64,12 @@ public class SpatialMatrix {
/**
* Method used to update an object that is already present in the matrix. The method will remove
* and reinsert the object in this atomic operation.
* and reinsert the object in this atomic operation.<br />
* <br />
*
* <b>Note</b> that this call will insert an object into the matrix if it wasn't previously
* already present. This follows that an object can only be updated in the scope of the tangible
* interface if it has been added before. Hence, we assume the addition was missed.
*
* @param object
* The object to update.
......@@ -233,9 +238,6 @@ public class SpatialMatrix {
*/
public synchronized List<TangibleObject> below(int objectId) {
int index = findVerticalIndexFor(objectId) + 1;
// BUG if nothing is beloww, the index might be greater than the size of the array.
return new ArrayList<>(vertical.subList(index, vertical.size()));
}
......@@ -245,7 +247,8 @@ public class SpatialMatrix {
*
* @param objectIds
* The identifiers of all objects for which to retrieve objects to the left of.
* @return
* @return A {@link List} of {@link TangibleObject} instances which are considered to be to the
* left of at least one of the given objects.
*/
public synchronized List<TangibleObject> leftOf(List<Integer> objectIds) {
LinkedHashSet<TangibleObject> objects = new LinkedHashSet<>();
......@@ -255,6 +258,15 @@ public class SpatialMatrix {
return new ArrayList<>(objects);
}
/**
* Method used to retrieve all {@link TangibleObject} instances right of any of the given
* objects (by ID). Will call {@link #rightOf(int)} for each ID.
*
* @param objectIds
* The identifiers of all objects for which to retrieve objects to the right of.
* @return A {@link List} of {@link TangibleObject} instances which are considered to be to the
* right of at least one of the given objects.
*/
public synchronized List<TangibleObject> rightOf(List<Integer> objectIds) {
LinkedHashSet<TangibleObject> objects = new LinkedHashSet<>();
......@@ -263,6 +275,15 @@ public class SpatialMatrix {
return new ArrayList<>(objects);
}
/**
* Method used to retrieve all {@link TangibleObject} instances above any of the given objects
* (by ID). Will call {@link #above(int)} for each ID.
*
* @param objectIds
* The identifiers of all objects for which to retrieve objects above of.
* @return A {@link List} of {@link TangibleObject} instances which are considered to be above
* at least one of the given objects.
*/
public synchronized List<TangibleObject> above(List<Integer> objectIds) {
LinkedHashSet<TangibleObject> objects = new LinkedHashSet<>();
......@@ -271,6 +292,15 @@ public class SpatialMatrix {
return new ArrayList<>(objects);
}
/**
* Method used to retrieve all {@link TangibleObject} instances below any of the given objects
* (by ID). Will call {@link #below(int)} for each ID.
*
* @param objectIds
* The identifiers of all objects for which to retrieve objects below of.
* @return A {@link List} of {@link TangibleObject} instances which are considered to be below
* at least one of the given objects.
*/
public synchronized List<TangibleObject> below(List<Integer> objectIds) {
LinkedHashSet<TangibleObject> objects = new LinkedHashSet<>();
......@@ -287,10 +317,7 @@ public class SpatialMatrix {
* are tied.
*/
public TangibleObject getLeftMostObject() {
if (horizontal.size() > 0)
return horizontal.get(0);
return null;
return horizontal.get(0);
}
/**
......@@ -301,10 +328,7 @@ public class SpatialMatrix {
* tied.
*/
public TangibleObject getRightMostObject() {
if (horizontal.size() > 0)
return horizontal.get(horizontal.size() - 1);
return null;
return horizontal.get(horizontal.size() - 1);
}
/**
......@@ -315,10 +339,7 @@ public class SpatialMatrix {
* are tied.
*/
public TangibleObject getTopObject() {
if (vertical.size() > 0)
return vertical.get(0);
return null;
return vertical.get(0);
}
/**
......@@ -329,10 +350,7 @@ public class SpatialMatrix {
* tied.
*/
public TangibleObject getBottomObject() {
if (vertical.size() > 0)
return vertical.get(vertical.size() - 1);
return null;
return vertical.get(vertical.size() - 1);
}
/**
......
......@@ -92,6 +92,15 @@ public class SpatialPositioningManager implements SpatialEventListener {
return INSTANCE;
}
/**
* Simple getter method for spatialMatrix.
*
* @return The value of spatialMatrix.
*/
public SpatialMatrix getSpatialMatrix() {
return spatialMatrix;
}
/**
* Method for configuring a {@link Logger} with several properties as given by the loader
* properties file.
......@@ -141,19 +150,19 @@ public class SpatialPositioningManager implements SpatialEventListener {
logger.log(Level.SEVERE, "Spatial event type \"" + event.getType() + "\" not recognized!"); //$NON-NLS-1$ //$NON-NLS-2$
break;
}
System.out.println(spatialMatrix.printLists());
System.out.println("Left of " + event.getSource().getObjectId() + ": " +
spatialMatrix.leftOf(event.getSource().getObjectId())); // $NON-NLS-1$
// //$NON-NLS-2$
System.out.println("Right of " + event.getSource().getObjectId() + ": " +
spatialMatrix.rightOf(event.getSource().getObjectId())); // $NON-NLS-1$
// //$NON-NLS-2$
System.out.println("Above " + event.getSource().getObjectId() + ": " +
spatialMatrix.above(event.getSource().getObjectId())); // $NON-NLS-1$
// //$NON-NLS-2$
System.out.println("Below " + event.getSource().getObjectId() + ": " +
spatialMatrix.below(event.getSource().getObjectId())); // $NON-NLS-1$
// //$NON-NLS-2$
// System.out.println(spatialMatrix.printLists());
// System.out.println("Left of " + event.getSource().getObjectId() + ": " +
// spatialMatrix.leftOf(event.getSource().getObjectId())); // $NON-NLS-1$
// // //$NON-NLS-2$
// System.out.println("Right of " + event.getSource().getObjectId() + ": " +
// spatialMatrix.rightOf(event.getSource().getObjectId())); // $NON-NLS-1$
// // //$NON-NLS-2$
// System.out.println("Above " + event.getSource().getObjectId() + ": " +
// spatialMatrix.above(event.getSource().getObjectId())); // $NON-NLS-1$
// // //$NON-NLS-2$
// System.out.println("Below " + event.getSource().getObjectId() + ": " +
// spatialMatrix.below(event.getSource().getObjectId())); // $NON-NLS-1$
// // //$NON-NLS-2$
}
/**
......@@ -161,13 +170,14 @@ public class SpatialPositioningManager implements SpatialEventListener {
* its x-axis coordinate. The retrieval is based on the underlying handles.
*
* @return The widget with the smallest x-axis coordinate. Returns the first if more than one
* are tied.
* are tied. Will return <code>null</code> if no object is present.
*/
public BaseWidget getLeftMostWidget() {
if (spatialMatrix.getLeftMostObject() == null)
if (getLeftMostObject() == null) {
return null;
}
return TangibleObjectManager.getWidget(spatialMatrix.getLeftMostObject().getObjectId());
return TangibleObjectManager.getWidget(getLeftMostObject().getObjectId());
}
/**
......@@ -185,13 +195,13 @@ public class SpatialPositioningManager implements SpatialEventListener {
* its x-axis coordinate. The retrieval is based on the underlying handles.
*
* @return The widget with the largest x-axis coordinate. Returns the last if more than one are
* tied.
* tied. Will return <code>null</code> if no object is present.
*/
public BaseWidget getRightMostWidget() {
if (spatialMatrix.getRightMostObject() == null)
if (getRightMostObject() == null)
return null;
return TangibleObjectManager.getWidget(spatialMatrix.getRightMostObject().getObjectId());
return TangibleObjectManager.getWidget(getRightMostObject().getObjectId());
}
/**
......@@ -208,11 +218,12 @@ public class SpatialPositioningManager implements SpatialEventListener {
* its y-axis coordinate. The retrieval is based on the underlying handles.
*
* @return The widget with the smallest y-axis coordinate. Returns the first if more than one
* are tied.
* are tied. Will return <code>null</code> if no object is present.
*/
public BaseWidget getTopWidget() {
if (spatialMatrix.getTopObject() == null)
if (getTopObject() == null) {
return null;
}
return TangibleObjectManager.getWidget(spatialMatrix.getTopObject().getObjectId());
}
......@@ -231,13 +242,14 @@ public class SpatialPositioningManager implements SpatialEventListener {
* its y-axis coordinate. The retrieval is based on the underlying handles.
*
* @return The widget with the largest y-axis coordinate. Returns the last if more than one are
* tied.
* tied. Will return <code>null</code> if no object is present.
*/
public BaseWidget getBottomWidget() {
if (spatialMatrix.getBottomObject() == null)
if (getBottomObject() == null) {
return null;
}
return TangibleObjectManager.getWidget(spatialMatrix.getBottomObject().getObjectId());
return TangibleObjectManager.getWidget(getBottomObject().getObjectId());
}
/**
......@@ -391,4 +403,12 @@ public class SpatialPositioningManager implements SpatialEventListener {
return widgets;
}
/**
* Method used to reinitialize the spatial matrix held by this class. Mostly used during unit
* testing.
*/
public void reinitialize() {
spatialMatrix = new SpatialMatrix();
}
}
\ No newline at end of file
......@@ -4,8 +4,8 @@
* This file is part of TULIP.
*
* 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 Foundation, version 3 of
* the License.
* 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
......@@ -65,7 +65,7 @@ public class TangibleObjectTest {
/**
* Class implementing the abstract {@link TangibleApplication} for test purposes.
*
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @author Eric TOBIAS [eric.tobias@list.lu]
* @since 13 Mar 2014
* @version 1
*/
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2015. All rights reserved.
*
* This file is part of TULIP.
*
* 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 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
* 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>.
*/
package lu.list.itis.dkd.tui.space;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.TangibleApplication;
import lu.list.itis.dkd.tui.TangibleInterfaceManager;
import lu.list.itis.dkd.tui.TangibleObjectManager;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.adapter.TangibleObject.Type;
import lu.list.itis.dkd.tui.adapter.TangibleObjectBuilder;
import lu.list.itis.dkd.tui.adapter.TuiAdapter;
import lu.list.itis.dkd.tui.event.SpatialEvent;
import lu.list.itis.dkd.tui.event.SpatialEvent.SpatialEventType;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.BaseWidget;
import lu.list.itis.dkd.tui.widget.builder.BaseWidgetBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
/**
* Unit tests for the {@link SpatialMatrix} class.
*
* @author Eric Tobias [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.3
*/
public class SpatialMatrixTest {
/**
* Class implementing the abstract {@link TangibleApplication} for test purposes.
*
* @author Eric Tobias [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.3
*/
public class TestTangibleApplication extends TangibleApplication {
/**
* Constructor initialising several basic properties.
*
* @param newPropertiesFileURI
* The URI of the properties file to load.
* @throws Exception
*/
protected TestTangibleApplication(String newPropertiesFileURI) throws Exception {
super(newPropertiesFileURI);
objectManager = new TestTangibleObjectManager(this, TangibleApplication.logger, properties);
objectManager.defineWidgets();
this.adapter.setObjectManager(objectManager);
this.adapter.addListener(SpatialPositioningManager.getInstance());
}
@SuppressWarnings("javadoc")
public TuiAdapter getAdapter() {
return this.adapter;
}
}
/**
* Class implementing the abstract {@link TangibleApplication} for test purposes.
*
* @author Eric Tobias [eric.tobias@tudor.lu]
* @since 2.1
* @version 2.1.3
*/
@SuppressWarnings("serial")
public class TestTangibleInterfaceManager extends TangibleInterfaceManager {
/**
* @see TangibleInterfaceManager
*/
@SuppressWarnings("javadoc")
public TestTangibleInterfaceManager(TangibleApplication applicationContext, Logger applicationLogger, Properties properties) {
super(applicationContext, applicationLogger, properties);
}
}
/**
* Class implementing the abstract {@link TangibleObjectManager} for test purposes.
*
* @author Eric Tobias [eric.tobias@tudor.lu]
* @since 2.1
* @version 2.1.3
*/
public class TestTangibleObjectManager extends TangibleObjectManager {
/**
* Constructor initialising several fields and setting up the list of managed tangibles.
*
* @param applicationContext
* The {@link TangibleApplication} hosting this manager.
* @param applicationLogger
* The {@link Logger} to use for all logging purposes.
* @param properties
* The properties instance from which to load the default values from.
*/
@NonNullByDefault
public TestTangibleObjectManager(TangibleApplication applicationContext, Logger applicationLogger, Properties properties) {
super(applicationContext, applicationLogger, properties);
}
/**
* {@inheritDoc}
*/
@Override
public void defineWidgets() throws BuildException {
BaseWidget baseWidget = new BaseWidgetBuilder()
.withHandle(0, new Point(0, 0, 0))
.build();
objectList.put(0, baseWidget);
BaseWidget baseWidget_1 = new BaseWidgetBuilder()
.withHandle(1, new Point(10, 10, 10))
.build();
objectList.put(1, baseWidget_1);
BaseWidget baseWidget_2 = new BaseWidgetBuilder()
.withHandle(2, new Point(20, 20, 20))
.build();
objectList.put(2, baseWidget_2);
BaseWidget baseWidget_3 = new BaseWidgetBuilder()
.withHandle(3, new Point(30, 30, 30))
.build();
objectList.put(3, baseWidget_3);
BaseWidget baseWidget_4 = new BaseWidgetBuilder()
.withHandle(4, new Point(40, 40, 40))
.build();
objectList.put(4, baseWidget_4);
}
}
private TestTangibleApplication application;
private static TangibleObjectBuilder builderZero;
private static TangibleObjectBuilder builderOne;
private static TangibleObjectBuilder builderTwo;
private static TangibleObjectBuilder builderThree;
private static TangibleObjectBuilder builderFour;
private TangibleObject objectZero;
private TangibleObject objectOne;
private TangibleObject objectTwo;
private TangibleObject objectThree;
private TangibleObject objectFour;
private SpatialMatrix matrix;
/**
* @throws Exception
*
*/
@BeforeClass
public static void setUpBefore() throws Exception {
builderZero = new TangibleObjectBuilder(0, Type.OBJECT, 0, 0);
builderOne = new TangibleObjectBuilder(1, Type.CURSOR, 10, 10);
builderTwo = new TangibleObjectBuilder(2, Type.BLOB, 20, 20);
builderThree = new TangibleObjectBuilder(3, Type.OBJECT, 30, 30);
builderFour = new TangibleObjectBuilder(4, Type.CURSOR, 40, 40);
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
application = new TestTangibleApplication("test_properties.properties"); //$NON-NLS-1$
matrix = SpatialPositioningManager.getInstance().getSpatialMatrix();
objectZero = builderZero.build();
objectOne = builderOne.build();
objectTwo = builderTwo.build();
objectThree = builderThree.build();
objectFour = builderFour.build();
}
/**
* Method used to reinitialize the spatial matrix after each test.
*/
@After
public void after() {
SpatialPositioningManager.getInstance().reinitialize();
}
/**
* Test method for
* {@link lu.list.itis.dkd.tui.space.SpatialMatrix#add(lu.list.itis.dkd.tui.adapter.TangibleObject)}
* .
*/
@Test
public void testAdd() {
assertEquals(0, matrix.getVertical().size());
assertEquals(0, matrix.getHorizontal().size());
application.getAdapter().notifyListeners(new SpatialEvent(objectThree, objectThree.