Commit f4e1739e authored by Eric Tobias's avatar Eric Tobias

2.1.0 - Added SpatialMatrix and removed spatial comparators as the behaviour wasn't consistent.

+ Added methods to retrieve position information to BaseWidget.
+ Updated behaviour to retrieve widgets from the TangibleObjectManager to also include cursors and blobs.
~ BaseBuilder now specifies the network adapter as Nullable.
parent d8ad4b93
......@@ -329,7 +329,7 @@ public class TangibleInterfaceManager extends JComponent {
}
if (tangibleApplication.getObjectManager() != null) {
for (BaseWidget widget : tangibleApplication.getObjectManager().getObjects()) {
for (BaseWidget widget : tangibleApplication.getObjectManager().getWidgets()) {
widget.paint(canvas2D);
}
}
......
......@@ -29,6 +29,7 @@ import lu.list.itis.dkd.tui.widget.corona.builder.ShadowBuilder;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;
import java.util.Vector;
......@@ -140,13 +141,17 @@ public abstract class TangibleObjectManager {
}
/**
* Method returning a collection of {@link BaseWidget} instances held by this manager.
* Method returning a collection of {@link BaseWidget} instances held by this manager. The
* method will return objects, cursors, and blobs.
*
* @return The collection of managed {@link BaseWidget} instances.
*/
public synchronized Collection<BaseWidget> getObjects() {
Preconditions.checkState(objectList.values() != null, "Critical failure, a values() call to an initialised dictionnary " + "should never return null."); //$NON-NLS-1$ //$NON-NLS-2$
return objectList.values();
public static synchronized Collection<BaseWidget> getWidgets() {
Collection<BaseWidget> widgets = new ArrayList<>();
widgets.addAll(objectList.values());
widgets.addAll(cursorList.values());
widgets.addAll(blobList.values());
return widgets;
}
/**
......@@ -158,8 +163,15 @@ public abstract class TangibleObjectManager {
* @return The {@link BaseWidget} or <code>null</code> if no {@link BaseWidget} was keyed to the
* identifier.
*/
public static synchronized @Nullable BaseWidget getObject(int identifier) {
return objectList.get(identifier) != null ? objectList.get(identifier) : cursorList.get(identifier);
public static synchronized @Nullable BaseWidget getWidget(int identifier) {
if (null != objectList.get(identifier)) {
return objectList.get(identifier);
}
if (null != cursorList.get(identifier)) {
return cursorList.get(identifier);
}
return blobList.get(identifier);
}
/**
......
......@@ -306,7 +306,20 @@ public class TangibleObject {
* @return The {@link Point} instance representing this objects location data.
*/
public Point getPosition() {
return new Point(this.getX(), this.getY(), this.getAngle(), Math.signum(this.rotationSpeed));
return path.get(path.size() - 1);
}
/**
* Method for retrieving one of the former positions of this instance.
*
* @param anteriority
* The number of steps in this instances path to go back. Note that if the anteriority is
* superior to the paths length, the first element will be returned.
* @return The position of this instance at the given "time" or the first position in the path
* if the "time" is greater then the recorded path's length.
*/
public Point getPreviousPosition(int anteriority) {
return path.get((anteriority >= path.size() ? 0 : path.size() - (anteriority + 1)));
}
/**
......@@ -489,4 +502,22 @@ public class TangibleObject {
public void setArea(float area) {
this.area = area;
}
@Override
public boolean equals(@Nullable Object that) {
if (this == that) {
return true;
}
if (that instanceof TangibleObject) {
return hashCode() == ((TangibleObject) that).hashCode();
}
return false;
}
@Override
public int hashCode() {
return getObjectId();
}
}
\ No newline at end of file
......@@ -21,8 +21,6 @@ import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.utility.ScreenCoordinates;
import com.google.common.base.Preconditions;
import java.util.EventObject;
/**
......@@ -54,17 +52,16 @@ public class SpatialEvent extends EventObject {
* the event.
* @param location
* The location the event was triggered on. Note that the location must be expressed in
* {@link ScreenCoordinates}.
* {@link ScreenCoordinates}. Otherwise the conversion will be done before the location
* is stored.
* @param type
* The type of the event that is to be triggered.
* @ore location.getState().getClass() == ScreenCoordinates.class
* @pre location.getState().getClass() == ScreenCoordinates.class
*/
public SpatialEvent(TangibleObject source, Point location, SpatialEventType type) {
super(source);
Preconditions.checkArgument(location.getState().getClass().equals(ScreenCoordinates.class), "The location must be given in screen coordinates!"); //$NON-NLS-1$
this.location = location;
this.location = location.toScreenCoordinates();
this.type = type;
}
......
/**
* 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 lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.utility.ScreenCoordinates;
import java.util.Comparator;
/**
* @author Eric Tobias [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.0
*/
@NonNullByDefault
public class HorizontalPositionComparator implements Comparator<TangibleObject> {
/**
* Method used to compare two {@link TangibleObject} instances. The method will return 0 if both
* instances are equal. None of the provided parameters may be <code>null</code>.
*
* The method will use {@link Double#compare(double, double)} on the x-axis position of the
* provided {@link TangibleObject} instances after retrieving and converting their points to
* {@link ScreenCoordinates}.
*/
@Override
public int compare(TangibleObject thisTangible, TangibleObject thatTangible) {
if (thisTangible.equals(thatTangible)) {
return 0;
}
return Double.compare(thisTangible.getPosition().toScreenCoordinates().getX(), thatTangible.getPosition().toScreenCoordinates().getX());
}
}
\ No newline at end of file
/**
* 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 lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import java.util.ArrayList;
/**
* @author Eric Tobias [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.1
*/
@NonNullByDefault
public class SpatialMatrix {
private ArrayList<TangibleObject> horizontal = new ArrayList<>();
private ArrayList<TangibleObject> vertical = new ArrayList<>();
/**
* Method used to add an element to the matrix. The method will insert the element into the
* matrix such that all elements horizontally to the left of have a smaller (or equal) x-axis
* coordinate and such that all elements on the vertical axis that are above this element have a
* smaller or equal y-axis coordinate.
*
* @param object
* The object to add.
*/
public void add(TangibleObject object) {
object.getPosition().toScreenCoordinates();
horizontal.add(findHorizontalIndexFor(object), object);
vertical.add(findVerticalIndexFor(object), object);
}
/**
* Method to remove an element from the matrix. The method will remove the object from the
* matrix space.
*
* @param object
* The object to remove.
*/
public void remove(TangibleObject object) {
horizontal.remove(object);
vertical.remove(object);
}
/**
* 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.
*
* @param object
* The object to update.
*/
public synchronized void update(TangibleObject object) {
remove(object);
add(object);
}
/**
* Method used to find the index of the first horizontal object whose x-axis coordinate is
* bigger than this object's. Returns the size of the horizontal list if no such element could
* be found.
*
* @param object
* The object to look up the insertion index for.
* @return The index to add the element or the size of the list if the element should be added
* at the end.
*/
private int findHorizontalIndexFor(TangibleObject object) {
for (int index = 0; index < horizontal.size(); index++) {
if (Double.compare(object.getPosition().getX(), horizontal.get(index).getPosition().getX()) <= 0) {
return index;
}
}
return horizontal.size();
}
/**
* Method used to find the index of the first horizontal object whose x-axis coordinate is
* bigger than this object's. Returns the size of the horizontal list if no such element could
* be found.
*
* @param object
* The object to look up the insertion index for.
* @return The index to add the element or the size of the list if the element should be added
* at the end.
*/
private int findVerticalIndexFor(TangibleObject object) {
for (int index = 0; index < vertical.size(); index++) {
if (Double.compare(object.getPosition().getY(), vertical.get(index).getPosition().getY()) <= 0) {
return index;
}
}
return vertical.size();
}
public void printLists() {
StringBuilder verticalBuilder = new StringBuilder();
StringBuilder horizontalbuilder = new StringBuilder();
vertical.forEach(object -> verticalBuilder.append(object.getObjectId() + ", ")); //$NON-NLS-1$
horizontal.forEach(object -> horizontalbuilder.append(object.getObjectId() + ", ")); //$NON-NLS-1$
System.out.println("Vertical : " + verticalBuilder.toString()); //$NON-NLS-1$
System.out.println("Horizontal : " + horizontalbuilder.toString()); //$NON-NLS-1$
}
}
\ No newline at end of file
......@@ -16,7 +16,6 @@
*/
package lu.list.itis.dkd.tui.space;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.event.SpatialEvent;
import lu.list.itis.dkd.tui.event.SpatialEventListener;
import lu.list.itis.dkd.tui.utility.PropertiesFetcher;
......@@ -25,7 +24,6 @@ import com.google.common.base.Preconditions;
import java.io.IOException;
import java.util.Properties;
import java.util.TreeSet;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -48,18 +46,17 @@ import java.util.logging.Logger;
*/
public class SpatialPositioningManager implements SpatialEventListener {
private static final SpatialPositioningManager INSTANCE = new SpatialPositioningManager();
private static final Logger logger = Logger.getLogger(SpatialPositioningManager.class.getSimpleName());
private static final Properties properties = PropertiesFetcher.fetchProperties();
private static final SpatialPositioningManager INSTANCE = new SpatialPositioningManager();
private TreeSet<TangibleObject> horizontalOrder = new TreeSet<>(new HorizontalPositionComparator());
private TreeSet<TangibleObject> verticalOrder = new TreeSet<>(new VerticalPositionComparator());
private SpatialMatrix spatialMatrix = new SpatialMatrix();
/**
* Constructor initializing all fields.
*/
private SpatialPositioningManager() {
// TODO Auto-generated constructor stub
configureLogger(logger);
}
/**
......@@ -67,7 +64,7 @@ public class SpatialPositioningManager implements SpatialEventListener {
*
* @return The only valid instance of this {@link SpatialPositioningManager}.
*/
public SpatialPositioningManager getInstance() {
public static SpatialPositioningManager getInstance() {
return INSTANCE;
}
......@@ -79,8 +76,8 @@ public class SpatialPositioningManager implements SpatialEventListener {
* The {@link Logger} instance to configure.
* @pre logger != null
*/
public static void configureLogger(final Logger unconfiguredLogger) {
Preconditions.checkArgument(unconfiguredLogger != null, "The provider logger must not be null!"); //$NON-NLS-1$
private static void configureLogger(final Logger unconfiguredLogger) {
Preconditions.checkArgument(unconfiguredLogger != null, "The provided logger must not be null!"); //$NON-NLS-1$
if (Boolean.parseBoolean(properties.getProperty("logger.event.output.enabled"))) { //$NON-NLS-1$
try {
......@@ -98,22 +95,18 @@ public class SpatialPositioningManager implements SpatialEventListener {
switch (event.getType()) {
case UPDATE:
horizontalOrder.remove(event.getSource());
verticalOrder.remove(event.getSource());
// The update call would need to remove and then reinsert the objects to trigger a
// rearrangement.
// $FALL-THROUGH$
spatialMatrix.update(event.getSource());
break;
case INSERT:
horizontalOrder.add(event.getSource());
verticalOrder.add(event.getSource());
spatialMatrix.add(event.getSource());
break;
case REMOVE:
horizontalOrder.remove(event.getSource());
verticalOrder.remove(event.getSource());
spatialMatrix.remove(event.getSource());
break;
default:
logger.log(Level.SEVERE, "Spatial event type \"" + event.getType() + "\" not recognized!"); //$NON-NLS-1$ //$NON-NLS-2$
break;
}
spatialMatrix.printLists();
}
}
\ No newline at end of file
/**
* 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 lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.utility.ScreenCoordinates;
import java.util.Comparator;
/**
* @author Eric Tobias [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.0
*/
public class VerticalPositionComparator implements Comparator<TangibleObject> {
/**
* Method used to compare two {@link TangibleObject} instances. The method will return 0 if both
* instances are equal. None of the provided parameters may be <code>null</code>.
*
* The method will use {@link Double#compare(double, double)} on the y-axis position of the
* provided {@link TangibleObject} instances after retrieving and converting their points to
* {@link ScreenCoordinates}.
*
* <b>Important</b>: the provided coordinate system for the screen uses an inverse y-axis.
*/
@Override
public int compare(TangibleObject thisTangible, TangibleObject thatTangible) {
if (thisTangible.equals(thatTangible)) {
return 0;
}
return Double.compare(thisTangible.getPosition().toScreenCoordinates().getY(), thatTangible.getPosition().toScreenCoordinates().getY());
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@
package lu.list.itis.dkd.tui.widget;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.logging.EventLogger;
import lu.list.itis.dkd.tui.network.adapter.NetworkAdapter;
......@@ -40,7 +41,7 @@ import java.util.List;
*
* @author Eric TOBIAS [eric.tobias@list.lu]
* @since 1.0
* @version 1.0.2
* @version 2.1.1
*/
@NonNullByDefault
public class BaseWidget {
......@@ -50,7 +51,7 @@ public class BaseWidget {
protected HashMap<Integer, Point> positions;
/** The name given to this widget. */
protected String name;
@Nullable
protected NetworkAdapter networkAdapter;
/**
......@@ -76,7 +77,7 @@ public class BaseWidget {
* The {@link TangibleObject} that was triggering the move.
*/
public void actionMove(TangibleObject tangibleObject) {
EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), "move", tangibleObject.getTotalMilliseconds());
EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), "move", tangibleObject.getTotalMilliseconds()); //$NON-NLS-1$
positions.put(tangibleObject.getObjectId(), new Point(tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), Math.signum(tangibleObject.getRotationSpeed())));
updateCoronas(tangibleObject.getObjectId());
}
......@@ -102,7 +103,7 @@ public class BaseWidget {
* The {@link TangibleObject} that was triggering the drop action.
*/
public void actionDrop(TangibleObject tangibleObject) {
EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), "down", tangibleObject.getTotalMilliseconds());
EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), "down", tangibleObject.getTotalMilliseconds()); //$NON-NLS-1$
actionMove(tangibleObject);
startDrawingIfAppropriate(tangibleObject.getObjectId());
}
......@@ -128,7 +129,7 @@ public class BaseWidget {
* The TangibleObject that was triggering the drop action.
*/
public void actionLift(TangibleObject tangibleObject) {
EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), "up", tangibleObject.getTotalMilliseconds());
EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), "up", tangibleObject.getTotalMilliseconds()); //$NON-NLS-1$
actionMove(tangibleObject);
stopDrawing(tangibleObject.getObjectId());
}
......@@ -199,13 +200,37 @@ public class BaseWidget {
return results;
}
/**
* Method for returning the {@link Point} that holds the position at which the handle with the
* given ID resides.
*
* @param handleId
* The ID of the handle for which to retrieve the position.
* @return The {@link Point} holding the position of the parameterized (by its ID) handle.
* <code>null</code> if no such handle is managed.
*/
public Point getPosition(int handleId) {
return positions.get(handleId);
}
/**
* @return
* Simple getter method for positions.
*
* @return The value of positions.
*/
public NetworkAdapter getNetworkAdapter() {
return networkAdapter;
public HashMap<Integer, Point> getPositions() {
return positions;
}
/**
* Method for returning the {@link NetworkAdapter} referenced by this instance.
*
* @return The {@link NetworkAdapter} held by this instance or <code>null</code> if no adapter
* was assigned.
*/
@Nullable
public NetworkAdapter getNetworkAdapter() {
return networkAdapter;
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@
package lu.list.itis.dkd.tui.widget.builder;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.network.adapter.NetworkAdapter;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.BaseWidget;
......@@ -45,7 +46,7 @@ public abstract class BaseBuilder<B extends BaseBuilder<B>> {
public HashMap<Integer, Point> positions;
/** The name that will be given to the widget. */
public String name;
@Nullable
public NetworkAdapter networkAdapter;
/** Constructor initialising the fields. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment