sheetMap = new HashMap<>();
+
+ public String get(String cell) {
+ String value = getLiteral(cell);
+ try {
+ Double.parseDouble(value);
+ return value.trim();
+ } catch (NumberFormatException n) {
+ return value;
+ }
+ }
+
+ public void put(String cell, String cellValue) {
+ sheetMap.put(cell, cellValue);
+ }
+
+ public String getLiteral(String cell) {
+ if (!containsCell(cell)) {
+ sheetMap.put(cell, "");
+ }
+ return sheetMap.get(cell);
+ }
+
+ private boolean containsCell(String cell) {
+ return sheetMap.containsKey(cell);
+ }
+}
diff --git a/src/voogasalad/rhondu/IComponent.java b/src/voogasalad/rhondu/IComponent.java
new file mode 100644
index 0000000..95742cd
--- /dev/null
+++ b/src/voogasalad/rhondu/IComponent.java
@@ -0,0 +1,85 @@
+package voogasalad.rhondu;
+
+import com.google.common.base.Preconditions;
+import javafx.beans.property.SimpleObjectProperty;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+
+/**
+ * This is the interface for all components, which hold data.
+ *
+ * @author Rhondu Smithwick, Tom Wu
+ */
+public interface IComponent {
+
+ /**
+ * Returns if only one of this component is allowed.
+ *
+ * @return whether only one of these components is allowed for an Entity
+ */
+ @Deprecated
+ default boolean unique() {
+ return false;
+ }
+
+ /**
+ * Gets any properties this component holds.
+ *
+ * @return all the properties this coompoennt holds
+ */
+ default List> getProperties() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Gets a specific property with specified value class and with specified name.
+ *
+ * Example call for a position:
+ * SimpleObjectProperty$Double$ x = position.getProperty(Double, "X");
+ *
+ * @param propertyClass the class of the property's held value
+ * @param name the name of property
+ * @param the type of the property's held value
+ * @return specific property of specified class and with name
+ * @throws IllegalArgumentException if incorrect propertyClass or no property with this name is present
+ */
+ @SuppressWarnings({"unchecked", "OptionalGetWithoutIsPresent"})
+ default SimpleObjectProperty getProperty(Class propertyClass, String name) throws IllegalArgumentException {
+ Predicate> isRight = (s) -> (Objects.equals(s.getName(), name));
+ Optional> rightProperty = getProperties().stream().filter(isRight).findFirst();
+ boolean hasProperty = rightProperty.isPresent();
+ Preconditions.checkArgument(hasProperty, "No such property with this name is present");
+ boolean rightClass = propertyClass.isInstance(rightProperty.get().get());
+ Preconditions.checkArgument(rightClass, "Incorrect value class");
+ return (SimpleObjectProperty) rightProperty.get();
+ }
+
+ /**
+ * Get a map, where each entry is a component name to it's value class.
+ *
+ * @return a map, where each entry is a component name to it's value class
+ */
+ default Map> getPropertyNamesAndClasses() {
+ Map> nameCLassMap = new HashMap<>();
+ for (SimpleObjectProperty> property : getProperties()) {
+ nameCLassMap.put(property.getName(), property.get().getClass());
+ }
+ return nameCLassMap;
+ }
+
+ /**
+ * Return the class to put into an entity map.
+ *
+ * @return the class to be put into an Entity map
+ */
+ default Class extends IComponent> getClassForComponentMap() {
+ return getClass();
+ }
+}
diff --git a/src/voogasalad/rhondu/SingleProperty.java b/src/voogasalad/rhondu/SingleProperty.java
new file mode 100644
index 0000000..ec76aa3
--- /dev/null
+++ b/src/voogasalad/rhondu/SingleProperty.java
@@ -0,0 +1,45 @@
+package voogasalad.rhondu;
+
+import javafx.beans.property.SimpleObjectProperty;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Holds one property of type A.
+ *
+ * @param the type of the first property
+ * @author Rhondu Smithwick
+ */
+public class SingleProperty {
+
+ private final SimpleObjectProperty property1;
+
+ /**
+ * Constructor.
+ *
+ * @param name1 of the property
+ * @param value1 initial value of the property
+ */
+ public SingleProperty(String name1, A value1) {
+ property1 = new SimpleObjectProperty<>(this, name1, value1);
+ }
+
+ /**
+ * Get first property.
+ *
+ * @return the first property
+ */
+ public SimpleObjectProperty property1() {
+ return property1;
+ }
+
+ /**
+ * Get the property as a list.
+ *
+ * @return the property as a list
+ */
+ public List> getProperties() {
+ return Collections.singletonList(property1());
+ }
+}
diff --git a/src/voogasalad/rhondu/TwoProperty.java b/src/voogasalad/rhondu/TwoProperty.java
new file mode 100644
index 0000000..25de709
--- /dev/null
+++ b/src/voogasalad/rhondu/TwoProperty.java
@@ -0,0 +1,49 @@
+package voogasalad.rhondu;
+
+import javafx.beans.property.SimpleObjectProperty;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Holds Two Properties and allows access to them.
+ *
+ * @param type of first property
+ * @param type of second property
+ * @author Rhondu Smithwick
+ */
+public class TwoProperty extends SingleProperty {
+
+ private final SimpleObjectProperty property2;
+
+ /**
+ * Constructor.
+ *
+ * @param name1 of the first property
+ * @param value1 starting value of the frist property
+ * @param name2 of the second property
+ * @param value2 starting value of the second property
+ */
+ public TwoProperty(String name1, A value1, String name2, B value2) {
+ super(name1, value1);
+ property2 = new SimpleObjectProperty<>(this, name2, value2);
+ }
+
+ /**
+ * Get the second property.
+ *
+ * @return the second property
+ */
+ public SimpleObjectProperty property2() {
+ return property2;
+ }
+
+ /**
+ * Get the properties as a list.
+ *
+ * @return the properties as a list
+ */
+ public List> getProperties() {
+ return Arrays.asList(property1(), property2());
+ }
+}
diff --git a/src/voogasalad/rhondu/Velocity.java b/src/voogasalad/rhondu/Velocity.java
new file mode 100644
index 0000000..1b74c6e
--- /dev/null
+++ b/src/voogasalad/rhondu/Velocity.java
@@ -0,0 +1,88 @@
+package voogasalad.rhondu;
+
+import javafx.beans.property.SimpleObjectProperty;
+
+import java.util.List;
+import java.util.function.DoubleUnaryOperator;
+
+
+/**
+ * Created by rhondusmithwick on 4/1/16.
+ *
+ * @author Rhondu Smithwick
+ */
+public class Velocity implements IComponent {
+
+ private final TwoProperty twoProperty;
+
+ public Velocity() {
+ twoProperty = new TwoProperty<>("Speed", 0.0, "Direction", 0.0);
+ }
+
+ public Velocity(double speed, double direction) {
+ this();
+ setSpeed(speed);
+ setDirection(direction);
+ }
+
+ public Velocity(double vx, double vy, boolean flag) {
+ this();
+ setVXY(vx, vy);
+ }
+
+ public double getSpeed() {
+ return speedProperty().get();
+ }
+
+ public void setSpeed(double speed) {
+ speedProperty().set(speed);
+ }
+
+ public SimpleObjectProperty speedProperty() {
+ return twoProperty.property1();
+ }
+
+ public double getDirection() {
+ return directionProperty().get();
+ }
+
+ public void setDirection(double direction) {
+ directionProperty().set(direction);
+ }
+
+ public SimpleObjectProperty directionProperty() {
+ return twoProperty.property2();
+ }
+
+ private double getVHelp(DoubleUnaryOperator func) {
+ double directionRadians = Math.toRadians(getDirection());
+ return getSpeed() * func.applyAsDouble(directionRadians);
+ }
+
+ public double getVX() {
+ return getVHelp(Math::cos);
+ }
+
+ public double getVY() {
+ return getVHelp(Math::sin);
+ }
+
+ public void setVXY(double vx, double vy) {
+ setSpeed(Math.sqrt(vx * vx + vy * vy));
+ setDirection(Math.toDegrees(Math.atan2(vy, vx)));
+ }
+
+ public void add(double dvx, double dvy) {
+ setVXY(getVX() + dvx, getVY() + dvy);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Velocity: [Speed: %s, Direction: %s]", getSpeed(), getDirection());
+ }
+
+ @Override
+ public List> getProperties() {
+ return twoProperty.getProperties();
+ }
+}
\ No newline at end of file
diff --git a/src/voogasalad/rhondu/VelocityTest.java b/src/voogasalad/rhondu/VelocityTest.java
new file mode 100644
index 0000000..26b9b49
--- /dev/null
+++ b/src/voogasalad/rhondu/VelocityTest.java
@@ -0,0 +1,61 @@
+package voogasalad.rhondu;
+
+import javafx.beans.property.SimpleObjectProperty;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by rhondusmithwick on 4/7/16.
+ *
+ * @author Rhondu Smithwick
+ */
+public class VelocityTest {
+
+ @Test
+ public void testInput() {
+ double speed = 800;
+ double direction = 20;
+ final Velocity velocity = new Velocity(speed, direction);
+ assertEquals(velocity.getSpeed(), speed, .001);
+ assertEquals(velocity.getDirection(), direction, .001);
+ }
+
+ @Test
+ public void testSet() {
+ double inSpeed = 800;
+ double inDirection = 20;
+ final Velocity velocity = new Velocity(inSpeed, inDirection);
+ double newSpeed = 100000;
+ velocity.setSpeed(newSpeed);
+ assertEquals(velocity.getSpeed(), newSpeed, .001);
+ double newDirection = 4000;
+ velocity.setDirection(newDirection);
+ assertEquals(velocity.getDirection(), newDirection, .001);
+ }
+
+ @Test
+ public void testProperties() {
+ double inSpeed = 800;
+ double inDirection = 20;
+ final Velocity velocity = new Velocity(inSpeed, inDirection);
+ SimpleObjectProperty speed = velocity.getProperty(Double.class, "Speed");
+ SimpleObjectProperty speedCheck = velocity.speedProperty();
+ assertEquals(speed, speedCheck);
+ }
+
+ @Test
+ public void testPropertiesMap() {
+ Map> testMap = new HashMap<>();
+ testMap.put("Speed", Double.class);
+ testMap.put("Direction", Double.class);
+ double inSpeed = 800;
+ double inDirection = 20;
+ final Velocity velocity = new Velocity(inSpeed, inDirection);
+ Map> velocityMap = velocity.getPropertyNamesAndClasses();
+ assertEquals(testMap, velocityMap);
+ }
+}