* Fixed assertion error bug in NativeObjectManager.deleteAllObjects()
* Fixed ID collision bug in NativeObjectManager by introducing NativeObject.getUniqueId() git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10637 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
1ac240e971
commit
dec182b13f
@ -59,4 +59,9 @@ public class AndroidAudioData extends AudioData {
|
|||||||
public NativeObject createDestructableClone() {
|
public NativeObject createDestructableClone() {
|
||||||
return new AndroidAudioData(id);
|
return new AndroidAudioData(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_AUDIOBUFFER << 32) | ((long)id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,4 +120,8 @@ public class AudioBuffer extends AudioData {
|
|||||||
return new AudioBuffer(id);
|
return new AudioBuffer(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_AUDIOBUFFER << 32) | ((long)id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,5 +199,8 @@ public class AudioStream extends AudioData implements Closeable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_AUDIOSTREAM << 32) | ((long)ids[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,4 +96,8 @@ public class LowPassFilter extends Filter {
|
|||||||
return new LowPassFilter(id);
|
return new LowPassFilter(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_FILTER << 32) | ((long)id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1004,6 +1004,11 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
|
|||||||
return new VertexBuffer(id);
|
return new VertexBuffer(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_VERTEXBUFFER << 32) | ((long)id);
|
||||||
|
}
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(components, "components", 0);
|
oc.write(components, "components", 0);
|
||||||
|
@ -155,6 +155,11 @@ public final class Shader extends NativeObject {
|
|||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_SHADERSOURCE << 32) | ((long)id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
String nameTxt = "";
|
String nameTxt = "";
|
||||||
@ -322,4 +327,8 @@ public final class Shader extends NativeObject {
|
|||||||
return new Shader(this);
|
return new Shader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_SHADER << 32) | ((long)id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,4 +501,9 @@ public class FrameBuffer extends NativeObject {
|
|||||||
public NativeObject createDestructableClone(){
|
public NativeObject createDestructableClone(){
|
||||||
return new FrameBuffer(this);
|
return new FrameBuffer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_FRAMEBUFFER << 32) | ((long)id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,6 +393,11 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ {
|
|||||||
return new Image(id);
|
return new Image(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUniqueId() {
|
||||||
|
return ((long)OBJTYPE_TEXTURE << 32) | ((long)id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A shallow clone of this image. The data is not cloned.
|
* @return A shallow clone of this image. The data is not cloned.
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +45,15 @@ public abstract class NativeObject implements Cloneable {
|
|||||||
|
|
||||||
public static final int INVALID_ID = -1;
|
public static final int INVALID_ID = -1;
|
||||||
|
|
||||||
|
protected static final int OBJTYPE_VERTEXBUFFER = 1,
|
||||||
|
OBJTYPE_TEXTURE = 2,
|
||||||
|
OBJTYPE_FRAMEBUFFER = 3,
|
||||||
|
OBJTYPE_SHADER = 4,
|
||||||
|
OBJTYPE_SHADERSOURCE = 5,
|
||||||
|
OBJTYPE_AUDIOBUFFER = 6,
|
||||||
|
OBJTYPE_AUDIOSTREAM = 7,
|
||||||
|
OBJTYPE_FILTER = 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object manager to which this NativeObject is registered to.
|
* The object manager to which this NativeObject is registered to.
|
||||||
*/
|
*/
|
||||||
@ -199,6 +208,14 @@ public abstract class NativeObject implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
public abstract NativeObject createDestructableClone();
|
public abstract NativeObject createDestructableClone();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a unique ID for this NativeObject. No other NativeObject shall
|
||||||
|
* have the same ID.
|
||||||
|
*
|
||||||
|
* @return unique ID for this NativeObject.
|
||||||
|
*/
|
||||||
|
public abstract long getUniqueId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reclaims native resources used by this NativeObject.
|
* Reclaims native resources used by this NativeObject.
|
||||||
* It should be safe to call this method or even use the object
|
* It should be safe to call this method or even use the object
|
||||||
|
@ -37,7 +37,7 @@ import java.lang.ref.ReferenceQueue;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Queue;
|
import java.util.HashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ public class NativeObjectManager {
|
|||||||
/**
|
/**
|
||||||
* List of currently active GLObjects.
|
* List of currently active GLObjects.
|
||||||
*/
|
*/
|
||||||
private IntMap<NativeObjectRef> refMap = new IntMap<NativeObjectRef>();
|
private HashMap<Long, NativeObjectRef> refMap = new HashMap<Long, NativeObjectRef>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of real objects requested by user for deletion.
|
* List of real objects requested by user for deletion.
|
||||||
@ -92,6 +92,7 @@ public class NativeObjectManager {
|
|||||||
|
|
||||||
this.realObj = new WeakReference<NativeObject>(obj);
|
this.realObj = new WeakReference<NativeObject>(obj);
|
||||||
this.objClone = obj.createDestructableClone();
|
this.objClone = obj.createDestructableClone();
|
||||||
|
assert objClone.getId() == obj.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ public class NativeObjectManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeObjectRef ref = new NativeObjectRef(refQueue, obj);
|
NativeObjectRef ref = new NativeObjectRef(refQueue, obj);
|
||||||
refMap.put(obj.getId(), ref);
|
refMap.put(obj.getUniqueId(), ref);
|
||||||
|
|
||||||
obj.setNativeObjectManager(this);
|
obj.setNativeObjectManager(this);
|
||||||
|
|
||||||
@ -125,30 +126,34 @@ public class NativeObjectManager {
|
|||||||
|
|
||||||
assert realObj == null || obj.getId() == realObj.getId();
|
assert realObj == null || obj.getId() == realObj.getId();
|
||||||
|
|
||||||
if (deleteGL && obj.getId() > 0) {
|
if (deleteGL) {
|
||||||
// Unregister it from cleanup list.
|
if (obj.getId() <= 0) {
|
||||||
NativeObjectRef ref2 = refMap.remove(obj.getId());
|
logger.log(Level.WARNING, "Object already deleted: {0}", obj.getClass().getSimpleName() + "/" + obj.getId());
|
||||||
if (ref2 == null) {
|
} else {
|
||||||
throw new IllegalArgumentException("This NativeObject is not " +
|
// Unregister it from cleanup list.
|
||||||
"registered in this NativeObjectManager");
|
NativeObjectRef ref2 = refMap.remove(obj.getUniqueId());
|
||||||
}
|
if (ref2 == null) {
|
||||||
|
throw new IllegalArgumentException("This NativeObject is not " +
|
||||||
|
"registered in this NativeObjectManager");
|
||||||
|
}
|
||||||
|
|
||||||
assert ref == null || ref == ref2;
|
assert ref == null || ref == ref2;
|
||||||
|
|
||||||
int id = obj.getId();
|
int id = obj.getId();
|
||||||
|
|
||||||
// Delete object from the GL driver
|
// Delete object from the GL driver
|
||||||
obj.deleteObject(rendererObject);
|
obj.deleteObject(rendererObject);
|
||||||
assert obj.getId() == NativeObject.INVALID_ID;
|
assert obj.getId() == NativeObject.INVALID_ID;
|
||||||
|
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
logger.log(Level.FINEST, "Deleted: {0}", obj.getClass().getSimpleName() + "/" + id);
|
logger.log(Level.FINEST, "Deleted: {0}", obj.getClass().getSimpleName() + "/" + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (realObj != null){
|
if (realObj != null){
|
||||||
// Note: make sure to reset them as well
|
// Note: make sure to reset them as well
|
||||||
// They may get used in a new renderer in the future
|
// They may get used in a new renderer in the future
|
||||||
realObj.resetObject();
|
realObj.resetObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deleteBufs && UNSAFE && realObj != null) {
|
if (deleteBufs && UNSAFE && realObj != null) {
|
||||||
@ -194,8 +199,8 @@ public class NativeObjectManager {
|
|||||||
*/
|
*/
|
||||||
public void deleteAllObjects(Object rendererObject){
|
public void deleteAllObjects(Object rendererObject){
|
||||||
deleteUnused(rendererObject);
|
deleteUnused(rendererObject);
|
||||||
for (IntMap.Entry<NativeObjectRef> entry : refMap) {
|
ArrayList<NativeObjectRef> refMapCopy = new ArrayList<NativeObjectRef>(refMap.values());
|
||||||
NativeObjectRef ref = entry.getValue();
|
for (NativeObjectRef ref : refMapCopy) {
|
||||||
deleteNativeObject(rendererObject, ref.objClone, ref, true, false);
|
deleteNativeObject(rendererObject, ref.objClone, ref, true, false);
|
||||||
}
|
}
|
||||||
assert refMap.size() == 0;
|
assert refMap.size() == 0;
|
||||||
@ -219,9 +224,9 @@ public class NativeObjectManager {
|
|||||||
* This is typically called when the context is restarted.
|
* This is typically called when the context is restarted.
|
||||||
*/
|
*/
|
||||||
public void resetObjects(){
|
public void resetObjects(){
|
||||||
for (IntMap.Entry<NativeObjectRef> entry : refMap) {
|
for (NativeObjectRef ref : refMap.values()) {
|
||||||
// Must use the real object here, for this to be effective.
|
// Must use the real object here, for this to be effective.
|
||||||
NativeObject realObj = entry.getValue().realObj.get();
|
NativeObject realObj = ref.realObj.get();
|
||||||
if (realObj == null) {
|
if (realObj == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user