1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.physics.bullet; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.utils.Disposable; 21 22 public class BulletBase implements Disposable { 23 private long cPointer; 24 protected boolean swigCMemOwn; 25 private boolean disposed; 26 protected boolean destroyed; 27 public final String className; 28 private int refCount; 29 BulletBase(final String className, long cPtr, boolean cMemoryOwn)30 protected BulletBase(final String className, long cPtr, boolean cMemoryOwn) { 31 this.className = className; 32 swigCMemOwn = cMemoryOwn; 33 cPointer = cPtr; 34 } 35 36 /** Obtains a reference to this object, call release to free the reference. */ obtain()37 public void obtain() { 38 refCount++; 39 } 40 41 /** Release a previously obtained reference, causing the object to be disposed when this was the last reference. */ release()42 public void release() { 43 if (--refCount <= 0 && Bullet.useRefCounting) 44 dispose(); 45 } 46 47 /** @return Whether this instance is obtained using the {@link #obtain()} method. */ isObtained()48 public boolean isObtained() { 49 return refCount > 0; 50 } 51 construct()52 protected void construct() { 53 destroyed = false; 54 } 55 reset(long cPtr, boolean cMemoryOwn)56 protected void reset(long cPtr, boolean cMemoryOwn) { 57 if (!destroyed) 58 destroy(); 59 swigCMemOwn = cMemoryOwn; 60 cPointer = cPtr; 61 construct(); 62 } 63 64 @Override equals(Object obj)65 public boolean equals(Object obj) { 66 return (obj instanceof BulletBase) && (((BulletBase)obj).cPointer == this.cPointer); 67 } 68 69 @Override hashCode()70 public int hashCode() { 71 return (int)cPointer; 72 } 73 74 /** @return The memory location (pointer) of this instance. */ getCPointer()75 public long getCPointer() { 76 return cPointer; 77 } 78 79 /** Take ownership of the native instance, causing the native object to be deleted when this object gets out of scope. */ takeOwnership()80 public void takeOwnership() { 81 swigCMemOwn = true; 82 } 83 84 /** Release ownership of the native instance, causing the native object NOT to be deleted when this object gets out of scope. */ releaseOwnership()85 public void releaseOwnership() { 86 swigCMemOwn = false; 87 } 88 89 /** @return True if the native is destroyed when this object gets out of scope, false otherwise. */ hasOwnership()90 public boolean hasOwnership() { 91 return swigCMemOwn; 92 } 93 94 /** Deletes the bullet object this class encapsulates. Do not call directly, instead use the {@link #dispose()} method. */ delete()95 protected void delete() { 96 cPointer = 0; 97 } 98 99 @Override dispose()100 public void dispose () { 101 if (refCount > 0 && Bullet.useRefCounting && Bullet.enableLogging) 102 Gdx.app.error("Bullet", "Disposing "+toString()+" while it still has "+refCount+" references."); 103 disposed = true; 104 delete(); 105 } 106 107 /** @return Whether the {@link #dispose()} method of this instance is called. */ isDisposed()108 public boolean isDisposed() { 109 return disposed; 110 } 111 112 @Override toString()113 public String toString () { 114 return className+"("+cPointer+","+swigCMemOwn+")"; 115 } 116 destroy()117 protected void destroy() { 118 try { 119 if (destroyed && Bullet.enableLogging) 120 Gdx.app.error("Bullet", "Already destroyed "+toString()); 121 destroyed = true; 122 123 if (swigCMemOwn && !disposed) { 124 if (Bullet.enableLogging) 125 Gdx.app.error("Bullet", "Disposing "+toString()+" due to garbage collection."); 126 dispose(); 127 } 128 } catch(Throwable e) { 129 Gdx.app.error("Bullet", "Exception while destroying "+toString(), e); 130 } 131 } 132 133 @Override finalize()134 protected void finalize() throws Throwable { 135 if (!destroyed && Bullet.enableLogging) 136 Gdx.app.error("Bullet", "The "+className+" class does not override the finalize method."); 137 super.finalize(); 138 } 139 }