DefineList: fix build error

Also add additional unit tests for DefineList.
experimental^2^2
Kirill Vainer 9 years ago
parent 9d035f747a
commit 6a47319dbb
  1. 25
      jme3-core/src/main/java/com/jme3/shader/DefineList.java
  2. 225
      jme3-core/src/test/java/com/jme3/shader/DefineListTest.java

@ -38,12 +38,10 @@ import java.util.List;
* *
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public final class DefineList implements Cloneable { public final class DefineList {
public static final int MAX_DEFINES = 64; public static final int MAX_DEFINES = 64;
public static final int SAVABLE_VERSION = 1;
private long hash; private long hash;
private final int[] vals; private final int[] vals;
@ -78,6 +76,18 @@ public final class DefineList implements Cloneable {
set(id, val ? 1 : 0); set(id, val ? 1 : 0);
} }
public boolean getBoolean(int id) {
return vals[id] != 0;
}
public float getFloat(int id) {
return Float.intBitsToFloat(vals[id]);
}
public int getInt(int id) {
return vals[id];
}
@Override @Override
public int hashCode() { public int hashCode() {
return (int)((hash >> 32) ^ hash); return (int)((hash >> 32) ^ hash);
@ -110,7 +120,7 @@ public final class DefineList implements Cloneable {
if (defineTypes != null && defineTypes.get(i) == VarType.Float) { if (defineTypes != null && defineTypes.get(i) == VarType.Float) {
float val = Float.intBitsToFloat(vals[i]); float val = Float.intBitsToFloat(vals[i]);
if (!Float.isFinite(val)) { if (Float.isInfinite(val) || Float.isNaN(val)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"GLSL does not support NaN " "GLSL does not support NaN "
+ "or Infinite float literals"); + "or Infinite float literals");
@ -123,6 +133,11 @@ public final class DefineList implements Cloneable {
sb.append("\n"); sb.append("\n");
} }
} }
System.out.println(sb.toString()); }
public String generateSource(List<String> defineNames, List<VarType> defineTypes) {
StringBuilder sb = new StringBuilder();
generateSource(sb, defineNames, defineTypes);
return sb.toString();
} }
} }

@ -33,13 +33,21 @@ package com.jme3.shader;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
public class DefineListTest { public class DefineListTest {
private List<String> defineNames; private static final List<String> DEFINE_NAMES = Arrays.asList("BOOL_VAR", "INT_VAR", "FLOAT_VAR");
private List<VarType> defineTypes; private static final List<VarType> DEFINE_TYPES = Arrays.asList(VarType.Boolean, VarType.Int, VarType.Float);
private static final int NUM_DEFINES = DEFINE_NAMES.size();
private static final int BOOL_VAR = 0;
private static final int INT_VAR = 1;
private static final int FLOAT_VAR = 2;
private static final DefineList EMPTY = new DefineList(NUM_DEFINES);
@Test @Test
public void testHashCollision() { public void testHashCollision() {
@ -58,86 +66,235 @@ public class DefineListTest {
assert dl1.equals(dl2); assert dl1.equals(dl2);
} }
@Test
public void testGetSet() {
DefineList dl = new DefineList(NUM_DEFINES);
assertFalse(dl.getBoolean(BOOL_VAR));
assertEquals(dl.getInt(INT_VAR), 0);
assertEquals(dl.getFloat(FLOAT_VAR), 0f, 0f);
dl.set(BOOL_VAR, true);
dl.set(INT_VAR, -1);
dl.set(FLOAT_VAR, Float.NaN);
assertTrue(dl.getBoolean(BOOL_VAR));
assertEquals(dl.getInt(INT_VAR), -1);
assertTrue(Float.isNaN(dl.getFloat(FLOAT_VAR)));
}
private String generateSource(DefineList dl) { private String generateSource(DefineList dl) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
dl.generateSource(sb, defineNames, defineTypes); dl.generateSource(sb, DEFINE_NAMES, DEFINE_TYPES);
return sb.toString(); return sb.toString();
} }
@Test @Test
public void testInitial() { public void testSourceInitial() {
DefineList dl = new DefineList(3); DefineList dl = new DefineList(NUM_DEFINES);
defineNames = Arrays.asList("A", "B", "C");
defineTypes = Arrays.asList(VarType.Boolean, VarType.Int, VarType.Float);
assert dl.hashCode() == 0; assert dl.hashCode() == 0;
assert generateSource(dl).equals(""); assert generateSource(dl).equals("");
} }
@Test @Test
public void testBooleanDefine() { public void testSourceBooleanDefine() {
DefineList dl = new DefineList(1); DefineList dl = new DefineList(NUM_DEFINES);
defineNames = Arrays.asList("BOOL_VAR");
defineTypes = Arrays.asList(VarType.Boolean);
dl.set(0, true); dl.set(BOOL_VAR, true);
assert dl.hashCode() == 1; assert dl.hashCode() == 1;
assert generateSource(dl).equals("#define BOOL_VAR 1\n"); assert generateSource(dl).equals("#define BOOL_VAR 1\n");
dl.set(0, false); dl.set(BOOL_VAR, false);
assert dl.hashCode() == 0; assert dl.hashCode() == 0;
assert generateSource(dl).equals(""); assert generateSource(dl).equals("");
} }
@Test @Test
public void testFloatDefine() { public void testSourceIntDefine() {
DefineList dl = new DefineList(1); DefineList dl = new DefineList(NUM_DEFINES);
defineNames = Arrays.asList("FLOAT_VAR");
defineTypes = Arrays.asList(VarType.Float);
dl.set(0, 1f); int hashCodeWithInt = 1 << INT_VAR;
assert dl.hashCode() == 1;
dl.set(INT_VAR, 123);
assert dl.hashCode() == hashCodeWithInt;
assert generateSource(dl).equals("#define INT_VAR 123\n");
dl.set(INT_VAR, 0);
assert dl.hashCode() == 0;
assert generateSource(dl).equals("");
dl.set(INT_VAR, -99);
assert dl.hashCode() == hashCodeWithInt;
assert generateSource(dl).equals("#define INT_VAR -99\n");
dl.set(INT_VAR, Integer.MAX_VALUE);
assert dl.hashCode() == hashCodeWithInt;
assert generateSource(dl).equals("#define INT_VAR 2147483647\n");
}
@Test
public void testSourceFloatDefine() {
DefineList dl = new DefineList(NUM_DEFINES);
dl.set(FLOAT_VAR, 1f);
assert dl.hashCode() == (1 << FLOAT_VAR);
assert generateSource(dl).equals("#define FLOAT_VAR 1.0\n"); assert generateSource(dl).equals("#define FLOAT_VAR 1.0\n");
dl.set(0, 0f); dl.set(FLOAT_VAR, 0f);
assert dl.hashCode() == 0; assert dl.hashCode() == 0;
assert generateSource(dl).equals(""); assert generateSource(dl).equals("");
dl.set(0, -1f); dl.set(FLOAT_VAR, -1f);
assert generateSource(dl).equals("#define FLOAT_VAR -1.0\n"); assert generateSource(dl).equals("#define FLOAT_VAR -1.0\n");
dl.set(0, FastMath.FLT_EPSILON); dl.set(FLOAT_VAR, FastMath.FLT_EPSILON);
assert generateSource(dl).equals("#define FLOAT_VAR 1.1920929E-7\n"); assert generateSource(dl).equals("#define FLOAT_VAR 1.1920929E-7\n");
dl.set(0, FastMath.PI); dl.set(FLOAT_VAR, FastMath.PI);
assert generateSource(dl).equals("#define FLOAT_VAR 3.1415927\n"); assert generateSource(dl).equals("#define FLOAT_VAR 3.1415927\n");
try { try {
dl.set(0, Float.NaN); dl.set(FLOAT_VAR, Float.NaN);
generateSource(dl); generateSource(dl);
assert false; assert false;
} catch (IllegalArgumentException ex) { } } catch (IllegalArgumentException ex) { }
try { try {
dl.set(0, Float.POSITIVE_INFINITY); dl.set(FLOAT_VAR, Float.POSITIVE_INFINITY);
generateSource(dl); generateSource(dl);
assert false; assert false;
} catch (IllegalArgumentException ex) { } } catch (IllegalArgumentException ex) { }
try { try {
dl.set(0, Float.NEGATIVE_INFINITY); dl.set(FLOAT_VAR, Float.NEGATIVE_INFINITY);
generateSource(dl); generateSource(dl);
assert false; assert false;
} catch (IllegalArgumentException ex) { } } catch (IllegalArgumentException ex) { }
} }
@Test @Test
public void testSourceGeneration() { public void testEqualsAndHashCode() {
DefineList dl = new DefineList(64); DefineList dl1 = new DefineList(NUM_DEFINES);
defineNames = Arrays.asList("BOOL_VAR", "INT_VAR", "FLOAT_VAR"); DefineList dl2 = new DefineList(NUM_DEFINES);
defineTypes = Arrays.asList(VarType.Boolean, VarType.Int, VarType.Float);
dl.set(0, true); assertTrue(dl1.hashCode() == 0);
dl.set(1, -1); assertEquals(dl1, dl2);
dl.set(2, Float.NaN);
dl1.set(BOOL_VAR, true);
assertTrue(dl1.hashCode() == 1);
assertNotSame(dl1, dl2);
dl2.set(BOOL_VAR, true);
assertEquals(dl1, dl2);
dl1.set(INT_VAR, 2);
assertTrue(dl1.hashCode() == (1|2));
assertNotSame(dl1, dl2);
dl2.set(INT_VAR, 2);
assertEquals(dl1, dl2);
dl1.set(BOOL_VAR, false);
assertTrue(dl1.hashCode() == 2);
assertNotSame(dl1, dl2);
}
@Test
public void testDeepClone() {
DefineList dl1 = new DefineList(NUM_DEFINES);
DefineList dl2 = dl1.deepClone();
assertFalse(dl1 == dl2);
assertTrue(dl1.equals(dl2));
assertTrue(dl1.hashCode() == dl2.hashCode());
dl1.set(BOOL_VAR, true);
dl2 = dl1.deepClone();
assertTrue(dl1.equals(dl2));
assertTrue(dl1.hashCode() == dl2.hashCode());
dl1.set(INT_VAR, 123);
assertFalse(dl1.equals(dl2));
assertFalse(dl1.hashCode() == dl2.hashCode());
dl2 = dl1.deepClone();
assertTrue(dl1.equals(dl2));
assertTrue(dl1.hashCode() == dl2.hashCode());
}
@Test
public void testGenerateSource() {
DefineList dl = new DefineList(NUM_DEFINES);
assertEquals("", generateSource(dl));
dl.set(BOOL_VAR, true);
assertEquals("#define BOOL_VAR 1\n", generateSource(dl));
dl.set(INT_VAR, 123);
assertEquals("#define BOOL_VAR 1\n" +
"#define INT_VAR 123\n", generateSource(dl));
dl.set(BOOL_VAR, false);
assertEquals("#define INT_VAR 123\n", generateSource(dl));
dl.set(BOOL_VAR, true);
// should have predictable ordering based on defineId
assertEquals("#define BOOL_VAR 1\n" +
"#define INT_VAR 123\n", generateSource(dl));
}
private static String doLookup(HashMap<DefineList, String> map, boolean boolVal, int intVal, float floatVal) {
DefineList dl = new DefineList(NUM_DEFINES);
dl.set(BOOL_VAR, boolVal);
dl.set(INT_VAR, intVal);
dl.set(FLOAT_VAR, floatVal);
return map.get(dl);
}
@Test
public void testHashLookup() {
String STR_EMPTY = "This is an empty define list";
String STR_INT = "This define list has an int value";
String STR_BOOL = "This define list just has boolean value set";
String STR_BOOL_INT = "This define list has both a boolean and int value";
String STR_BOOL_INT_FLOAT = "This define list has a boolean, int, and float value";
HashMap<DefineList, String> map = new HashMap<DefineList, String>();
DefineList lookup = new DefineList(NUM_DEFINES);
map.put(lookup.deepClone(), STR_EMPTY);
lookup.set(BOOL_VAR, true);
map.put(lookup.deepClone(), STR_BOOL);
lookup.set(BOOL_VAR, false);
lookup.set(INT_VAR, 123);
map.put(lookup.deepClone(), STR_INT);
lookup.set(BOOL_VAR, true);
map.put(lookup.deepClone(), STR_BOOL_INT);
lookup.set(FLOAT_VAR, FastMath.PI);
map.put(lookup.deepClone(), STR_BOOL_INT_FLOAT);
assertEquals(doLookup(map, false, 0, 0f), STR_EMPTY);
assertEquals(doLookup(map, false, 123, 0f), STR_INT);
assertEquals(doLookup(map, true, 0, 0f), STR_BOOL);
assertEquals(doLookup(map, true, 123, 0f), STR_BOOL_INT);
assertEquals(doLookup(map, true, 123, FastMath.PI), STR_BOOL_INT_FLOAT);
} }
} }

Loading…
Cancel
Save