* Some optimizations for defines and shader key. Computing "compiled" define list isn't necessary to execute a lookup against asset manager. Allows faster changes in defines.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9771 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
1a12437436
commit
8efd28da76
@ -35,13 +35,15 @@ package com.jme3.shader;
|
|||||||
import com.jme3.export.*;
|
import com.jme3.export.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
public class DefineList implements Savable {
|
public class DefineList implements Savable, Cloneable {
|
||||||
|
|
||||||
private final SortedMap<String, String> defines = new TreeMap<String, String>();
|
private static final String ONE = "1";
|
||||||
|
|
||||||
|
private TreeMap<String, String> defines = new TreeMap<String, String>();
|
||||||
private String compiled = null;
|
private String compiled = null;
|
||||||
|
private int cachedHashCode = 0;
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException{
|
public void write(JmeExporter ex) throws IOException{
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
@ -73,46 +75,66 @@ public class DefineList implements Savable {
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
defines.clear();
|
defines.clear();
|
||||||
compiled = "";
|
compiled = "";
|
||||||
|
cachedHashCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String get(String key){
|
public String get(String key){
|
||||||
return defines.get(key);
|
return defines.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefineList clone() {
|
||||||
|
try {
|
||||||
|
DefineList clone = (DefineList) super.clone();
|
||||||
|
clone.cachedHashCode = 0;
|
||||||
|
clone.compiled = null;
|
||||||
|
clone.defines = (TreeMap<String, String>) defines.clone();
|
||||||
|
return clone;
|
||||||
|
} catch (CloneNotSupportedException ex) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean set(String key, VarType type, Object val){
|
public boolean set(String key, VarType type, Object val){
|
||||||
if (val == null){
|
if (val == null){
|
||||||
defines.remove(key);
|
defines.remove(key);
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type){
|
switch (type){
|
||||||
case Boolean:
|
case Boolean:
|
||||||
if (((Boolean) val).booleanValue()) {
|
if (((Boolean) val).booleanValue()) {
|
||||||
// same literal, != should work
|
// same literal, != will work
|
||||||
if (defines.put(key, "1") != "1") {
|
if (defines.put(key, ONE) != ONE) {
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (defines.containsKey(key)) {
|
} else if (defines.containsKey(key)) {
|
||||||
defines.remove(key);
|
defines.remove(key);
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Float:
|
case Float:
|
||||||
case Int:
|
case Int:
|
||||||
String original = defines.put(key, val.toString());
|
String newValue = val.toString();
|
||||||
|
String original = defines.put(key, newValue);
|
||||||
if (!val.equals(original)) {
|
if (!val.equals(original)) {
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// same literal, != should work
|
// same literal, != will work
|
||||||
if (defines.put(key, "1") != "1") {
|
if (defines.put(key, ONE) != ONE) {
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -124,17 +146,18 @@ public class DefineList implements Savable {
|
|||||||
public boolean remove(String key){
|
public boolean remove(String key){
|
||||||
if (defines.remove(key) != null) {
|
if (defines.remove(key) != null) {
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFrom(DefineList other){
|
public void addFrom(DefineList other){
|
||||||
if (other == null)
|
if (other == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
compiled = null;
|
compiled = null;
|
||||||
|
cachedHashCode = 0;
|
||||||
defines.putAll(other.defines);
|
defines.putAll(other.defines);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,15 +173,29 @@ public class DefineList implements Savable {
|
|||||||
return compiled;
|
return compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
final DefineList other = (DefineList) obj;
|
||||||
|
return defines.equals(other.defines);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (cachedHashCode == 0) {
|
||||||
|
cachedHashCode = defines.hashCode();
|
||||||
|
}
|
||||||
|
return cachedHashCode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Map.Entry<String, String> entry : defines.entrySet()) {
|
for (Map.Entry<String, String> entry : defines.entrySet()) {
|
||||||
sb.append(entry.getKey());
|
sb.append(entry.getKey()).append("=").append(entry.getValue());
|
||||||
if (i != defines.size() - 1)
|
if (i != defines.size() - 1) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -45,6 +45,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
protected DefineList defines;
|
protected DefineList defines;
|
||||||
protected String vertLanguage;
|
protected String vertLanguage;
|
||||||
protected String fragLanguage;
|
protected String fragLanguage;
|
||||||
|
protected int cachedHashedCode = 0;
|
||||||
|
|
||||||
public ShaderKey(){
|
public ShaderKey(){
|
||||||
}
|
}
|
||||||
@ -57,6 +58,14 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
this.fragLanguage = fragLanguage;
|
this.fragLanguage = fragLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderKey clone() {
|
||||||
|
ShaderKey clone = (ShaderKey) super.clone();
|
||||||
|
clone.cachedHashedCode = 0;
|
||||||
|
clone.defines = defines.clone();
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "V="+name + " F=" + fragName + (defines != null ? defines : "");
|
return "V="+name + " F=" + fragName + (defines != null ? defines : "");
|
||||||
@ -64,32 +73,29 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == null){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ShaderKey other = (ShaderKey) obj;
|
final ShaderKey other = (ShaderKey) obj;
|
||||||
if (name.equals(other.name) && fragName.equals(other.fragName)){
|
if (name.equals(other.name) && fragName.equals(other.fragName)){
|
||||||
if (defines != null && other.defines != null)
|
if (defines != null && other.defines != null) {
|
||||||
return defines.getCompiled().equals(other.defines.getCompiled());
|
return defines.equals(other.defines);
|
||||||
else if (defines != null || other.defines != null)
|
} else if (defines != null || other.defines != null) {
|
||||||
return false;
|
return false;
|
||||||
else
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
if (cachedHashedCode == 0) {
|
||||||
int hash = 7;
|
int hash = 7;
|
||||||
hash = 41 * hash + name.hashCode();
|
hash = 41 * hash + name.hashCode();
|
||||||
hash = 41 * hash + fragName.hashCode();
|
hash = 41 * hash + fragName.hashCode();
|
||||||
hash = 41 * hash + (defines != null ? defines.getCompiled().hashCode() : 0);
|
hash = 41 * hash + (defines != null ? defines.hashCode() : 0);
|
||||||
return hash;
|
cachedHashedCode = hash;
|
||||||
|
}
|
||||||
|
return cachedHashedCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefineList getDefines() {
|
public DefineList getDefines() {
|
||||||
@ -126,6 +132,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(fragName, "fragment_name", null);
|
oc.write(fragName, "fragment_name", null);
|
||||||
oc.write(vertLanguage, "language", null);
|
oc.write(vertLanguage, "language", null);
|
||||||
|
oc.write(fragLanguage, "frag_language", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -134,6 +141,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
fragName = ic.readString("fragment_name", null);
|
fragName = ic.readString("fragment_name", null);
|
||||||
vertLanguage = ic.readString("language", null);
|
vertLanguage = ic.readString("language", null);
|
||||||
|
fragLanguage = ic.readString("frag_language", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user