java-gobject-introspection r126 - in trunk: src/org/gnome/gir/compiler src/org/gnome/gir/gobject src/org/gnome/gir/repository stub-examples
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r126 - in trunk: src/org/gnome/gir/compiler src/org/gnome/gir/gobject src/org/gnome/gir/repository stub-examples
- Date: Sun, 16 Nov 2008 23:58:56 +0000 (UTC)
Author: walters
Date: Sun Nov 16 23:58:56 2008
New Revision: 126
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=126&view=rev
Log:
Massive refactoring of memmgt
Strip out a lot of stuff from NativeObject that we really don't need since
we aren't trying to handle non-GObjects in any serious way right now.
GObject now just subclasses NativeObject. RefCountedObject is a temporary
hack.
Modified:
trunk/src/org/gnome/gir/compiler/CodeFactory.java
trunk/src/org/gnome/gir/gobject/GInitiallyUnowned.java
trunk/src/org/gnome/gir/gobject/GMainContext.java
trunk/src/org/gnome/gir/gobject/GObject.java
trunk/src/org/gnome/gir/gobject/GObjectAPI.java
trunk/src/org/gnome/gir/gobject/GSource.java
trunk/src/org/gnome/gir/gobject/GTypeMapper.java
trunk/src/org/gnome/gir/gobject/Handle.java
trunk/src/org/gnome/gir/gobject/NativeObject.java
trunk/src/org/gnome/gir/gobject/RefCountedObject.java
trunk/src/org/gnome/gir/repository/BaseInfo.java
trunk/src/org/gnome/gir/repository/Repository.java
trunk/stub-examples/Test.java
Modified: trunk/src/org/gnome/gir/compiler/CodeFactory.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/CodeFactory.java (original)
+++ trunk/src/org/gnome/gir/compiler/CodeFactory.java Sun Nov 16 23:58:56 2008
@@ -1280,7 +1280,7 @@
/* These are objects for which we do *not* own a reference. */
mv.visitLdcInsn(ctx.returnType);
mv.visitInsn(ICONST_0);
- mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(NativeObject.class), "objectFor",
+ mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(NativeObject.Internals.class), "objectFor",
Type.getMethodDescriptor(getType(NativeObject.class), new Type[] { getType(Pointer.class), getType(Class.class), Type.BOOLEAN_TYPE }));
mv.visitTypeInsn(CHECKCAST, ctx.returnType.getInternalName());
} else if (returnTypeTag.equals(TypeTag.UTF8)) {
Modified: trunk/src/org/gnome/gir/gobject/GInitiallyUnowned.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GInitiallyUnowned.java (original)
+++ trunk/src/org/gnome/gir/gobject/GInitiallyUnowned.java Sun Nov 16 23:58:56 2008
@@ -2,18 +2,15 @@
public abstract class GInitiallyUnowned extends GObject {
-
+ /*
+ * Note - memory management for this class is handled inside GObject, we
+ * check whether an object is floating there.
+ */
public GInitiallyUnowned(Initializer init) {
super(init);
}
-
- @Override
- protected void ref() {
- GObjectAPI.gobj.g_object_ref_sink(this);
- }
protected GInitiallyUnowned(GType gtype, Object[] args) {
super(gtype, args);
}
-
}
Modified: trunk/src/org/gnome/gir/gobject/GMainContext.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GMainContext.java (original)
+++ trunk/src/org/gnome/gir/gobject/GMainContext.java Sun Nov 16 23:58:56 2008
@@ -63,18 +63,13 @@
return glib.g_source_attach(source, this);
}
public static GMainContext getDefaultContext() {
- return new GMainContext(initializer(glib.g_main_context_default(), false, false));
+ return new GMainContext(initializer(glib.g_main_context_default(), false));
}
protected void ref() {
- glib.g_main_context_ref(handle());
+ glib.g_main_context_ref(getNativeAddress());
}
protected void unref() {
- glib.g_main_context_unref(handle());
- }
-
- @Override
- protected void disposeNativeHandle(Pointer ptr) {
- glib.g_main_context_unref(ptr);
+ glib.g_main_context_unref(getNativeAddress());
}
}
Modified: trunk/src/org/gnome/gir/gobject/GObject.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GObject.java (original)
+++ trunk/src/org/gnome/gir/gobject/GObject.java Sun Nov 16 23:58:56 2008
@@ -51,7 +51,6 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.gnome.gir.gobject.GObjectAPI.GObjectStruct;
import org.gnome.gir.gobject.GObjectAPI.GParamSpec;
import org.gnome.gir.gobject.GObjectAPI.GToggleNotify;
import org.gnome.gir.gobject.GObjectAPI.GWeakNotify;
@@ -65,32 +64,11 @@
* This is an abstract class providing some GObject-like facilities in a common
* base class. Not intended for direct use.
*/
-public abstract class GObject extends RefCountedObject {
+public abstract class GObject extends NativeObject {
private static final Map<GObject, Boolean> strongReferences = new ConcurrentHashMap<GObject, Boolean>();
private final IntPtr objectID = new IntPtr(System.identityHashCode(this));
- private static final boolean debugMemory;
-
- static {
- debugMemory = System.getProperty("jgir.debugMemory") != null;
- }
-
- private static final void debugMemory(GObject obj, String fmt, Object... args) {
- if (debugMemory) {
- Object[] newArgs = new Object[args.length+2];
- System.arraycopy(args, 0, newArgs, 1, args.length);
- newArgs[0] = obj;
- if (obj != null) {
- GObjectStruct objStruct = new GObjectAPI.GObjectStruct(obj);
- newArgs[newArgs.length-1] = objStruct.ref_count;
- } else {
- newArgs[newArgs.length-1] = "<null>";
- }
- System.err.println(String.format(fmt, newArgs));
- }
- }
-
/* Hold a strong Java reference between this proxy object and any signal
* handlers installed. Often this would be done anyways, but if you're
* just calling System.out.println in a callback, it would otherwise
@@ -117,45 +95,46 @@
* return values of unmanaged code.
* @param init
*/
- public GObject(Initializer init) {
- super(init.ownsRef ? initializer(init.ptr, false, init.ownsHandle) : init);
- if (init.ownsHandle) {
- strongReferences.put(this, Boolean.TRUE);
-
- /* Floating refs are just a convenience for C; we always want only strong
- * nonfloating refs for objects which have a JVM peer.
- */
- boolean wasFloating = GObjectAPI.gobj.g_object_is_floating(this);
- if (wasFloating) {
- debugMemory(this, "SINK AND TOGGLE %s %s");
- GObjectAPI.gobj.g_object_ref_sink(this);
- } else {
- debugMemory(this, "TOGGLE %s %s");
- }
-
- /* The toggle reference is our primary means of memory management between
- * this Proxy object and the GObject.
- */
- GObjectAPI.gobj.g_object_add_toggle_ref(init.ptr, toggle, objectID);
-
- /* The weak notify is just a convenient hook into object destruction so we
- * can clear out our signal handlers hash.
- */
- GObjectAPI.gobj.g_object_weak_ref(this, weakNotify, null);
+ public GObject(Initializer init) {
+ super(init);
+
+ strongReferences.put(this, Boolean.TRUE);
- /*
- * Normally we have a strong reference given to us by constructors,
- * GValue property gets, etc. So here we unref, leaving the toggle
- * reference we just added.
- *
- * An example case where we don't own a ref are C convenience
- * getters - need to ensure those are annotated with (transfer
- * none).
- */
- if (init.ownsRef) {
- unref();
- }
- }
+ /*
+ * Floating refs are just a convenience for C; we always want only
+ * strong nonfloating refs for objects which have a JVM peer.
+ */
+ boolean wasFloating = GObjectAPI.gobj.g_object_is_floating(this);
+ if (wasFloating) {
+ NativeObject.Internals.debugMemory(this, "SINK AND TOGGLE %s %s");
+ GObjectAPI.gobj.g_object_ref_sink(this);
+ } else {
+ NativeObject.Internals.debugMemory(this, "TOGGLE %s %s");
+ }
+
+ /*
+ * The toggle reference is our primary means of memory management
+ * between this Proxy object and the GObject.
+ */
+ GObjectAPI.gobj.g_object_add_toggle_ref(init.ptr, toggle, objectID);
+
+ /*
+ * The weak notify is just a convenient hook into object destruction so
+ * we can clear out our signal handlers hash.
+ */
+ GObjectAPI.gobj.g_object_weak_ref(this, weakNotify, null);
+
+ /*
+ * Normally we have a strong reference given to us by constructors,
+ * GValue property gets, etc. So here we unref, leaving the toggle
+ * reference we just added.
+ *
+ * An example case where we don't own a ref are C convenience getters -
+ * need to ensure those are annotated with (transfer none).
+ */
+ if (init.ownsRef) {
+ GObjectAPI.gobj.g_object_unref(this);
+ }
}
private static Initializer getInitializer(GType gtype, Object[] args) {
@@ -208,8 +187,8 @@
* Sets the value of a <tt>GObject</tt> property.
*
* @param property The property to set.
- * @param data The value for the property. This must be of the type expected
- * by gstreamer.
+ * @param data The value for the property. This must be an instance of
+ * a class which maps to the corresponding GType.
*/
public void set(String property, Object data) {
GParamSpec propertySpec = findProperty(property);
@@ -241,38 +220,11 @@
return propValue.unboxAndUnset();
}
- protected void disposeNativeHandle(Pointer ptr) {
- GObjectAPI.gobj.g_object_remove_toggle_ref(ptr, toggle, objectID);
- }
- @Override
- protected void ref() {
- debugMemory(this, "REF %s %s");
- GObjectAPI.gobj.g_object_ref(this);
- }
-
- @Override
- protected void unref() {
- debugMemory(this, "UNREF %s %s");
- GObjectAPI.gobj.g_object_unref(this);
- }
-
@Override
- protected void invalidate() {
- try {
- debugMemory(this, "INVALIDATE %s %s");
- // Need to increase the ref count before removing the toggle ref, so
- // ensure the native object is not destroyed.
- if (ownsHandle.get()) {
- debugMemory(this, "REMOVING TOGGLE %s %s");
- ref();
-
- // Disconnect the callback.
- GObjectAPI.gobj.g_object_remove_toggle_ref(handle(), toggle, objectID);
- }
- strongReferences.remove(this);
- } finally {
- super.invalidate();
- }
+ protected void finalize() throws Throwable {
+ NativeObject.Internals.debugMemory(this, "REMOVING TOGGLE %s %s");
+ /* Take away the toggle reference */
+ GObjectAPI.gobj.g_object_remove_toggle_ref(getNativeAddress(), toggle, objectID);
}
public synchronized long connect(String signal, Callback closure) {
@@ -292,6 +244,7 @@
}
public synchronized long connectNotify(final String propName, final Callback callback) {
+ /* FIXME - need to hold this trampoline's lifecycle to the signal connection */
NotifyCallback trampoline = new NotifyCallback() {
@Override
public void onNotify(GObject object, GParamSpec param, Pointer data) {
@@ -323,7 +276,7 @@
}
private GObjectAPI.GParamSpec findProperty(String propertyName) {
- return GObjectAPI.gobj.g_object_class_find_property(handle().getPointer(0), propertyName);
+ return GObjectAPI.gobj.g_object_class_find_property(getNativeAddress().getPointer(0), propertyName);
}
/*
* Hooks to/from native disposal
@@ -337,10 +290,11 @@
* it a strong ref, so the java GObject for the underlying C object can
* be retained for later retrieval
*/
- GObject o = (GObject) NativeObject.instanceFor(ptr);
+ GObject o = (GObject) Internals.instanceFor(ptr);
if (o == null) {
return;
}
+ NativeObject.Internals.debugMemory(o, "TOGGLE %s %d %s", is_last_ref);
if (is_last_ref) {
strongReferences.remove(o);
} else {
@@ -352,8 +306,8 @@
private static final GWeakNotify weakNotify = new GWeakNotify() {
@Override
public void callback(Pointer data, Pointer obj) {
- GObject o = (GObject) NativeObject.instanceFor(obj);
- debugMemory(o, "WEAK %s %s obj=%s", o, obj);
+ GObject o = (GObject) Internals.instanceFor(obj);
+ NativeObject.Internals.debugMemory(o, "WEAK %s %s obj=%s", o, obj);
// Clear out the signal handler references
if (o == null)
return;
Modified: trunk/src/org/gnome/gir/gobject/GObjectAPI.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GObjectAPI.java (original)
+++ trunk/src/org/gnome/gir/gobject/GObjectAPI.java Sun Nov 16 23:58:56 2008
@@ -146,7 +146,7 @@
public volatile Pointer qdata;
public GObjectStruct() {}
public GObjectStruct(GObject obj) {
- useMemory(obj.handle());
+ useMemory(obj.getNativeAddress());
read();
}
}
Modified: trunk/src/org/gnome/gir/gobject/GSource.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GSource.java (original)
+++ trunk/src/org/gnome/gir/gobject/GSource.java Sun Nov 16 23:58:56 2008
@@ -63,7 +63,7 @@
public void setCallback(final Callable<Boolean> call) {
this.callback = new GSourceFunc() {
public boolean callback(Pointer data) {
- if (GlibAPI.glib.g_source_is_destroyed(handle())) {
+ if (GlibAPI.glib.g_source_is_destroyed(getNativeAddress())) {
return false;
}
try {
@@ -78,15 +78,9 @@
private GSourceFunc callback;
protected void ref() {
- GlibAPI.glib.g_source_ref(handle());
+ GlibAPI.glib.g_source_ref(getNativeAddress());
}
protected void unref() {
- GlibAPI.glib.g_source_unref(handle());
- }
-
- @Override
- protected void disposeNativeHandle(Pointer ptr) {
- GlibAPI.glib.g_source_destroy(ptr);
- GlibAPI.glib.g_source_unref(ptr);
+ GlibAPI.glib.g_source_unref(getNativeAddress());
}
}
Modified: trunk/src/org/gnome/gir/gobject/GTypeMapper.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GTypeMapper.java (original)
+++ trunk/src/org/gnome/gir/gobject/GTypeMapper.java Sun Nov 16 23:58:56 2008
@@ -101,7 +101,7 @@
if (arg == null) {
return null;
}
- Pointer ptr = ((NativeObject) arg).handle();
+ Pointer ptr = ((NativeObject) arg).getNativeAddress();
return ptr;
}
@@ -111,10 +111,10 @@
return null;
}
if (context instanceof FunctionResultContext) {
- return NativeObject.objectFor((Pointer) result, context.getTargetType(), true, true);
+ return NativeObject.Internals.objectFor((Pointer) result, context.getTargetType(), true);
}
if (context instanceof CallbackParameterContext || context instanceof StructureReadContext) {
- return NativeObject.objectFor((Pointer) result, context.getTargetType(), false, true);
+ return NativeObject.Internals.objectFor((Pointer) result, context.getTargetType(), false);
}
if (context instanceof MethodResultContext) {
throw new RuntimeException("Got illegal MethodResultContext in GTypeMapper");
Modified: trunk/src/org/gnome/gir/gobject/Handle.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/Handle.java (original)
+++ trunk/src/org/gnome/gir/gobject/Handle.java Sun Nov 16 23:58:56 2008
@@ -51,21 +51,19 @@
// Use this to propagate low level pointer arguments up the constructor chain
protected static class Initializer {
public final Pointer ptr;
- public final boolean ownsRef, ownsHandle;
+ public final boolean ownsRef;
public Initializer(Pointer ptr) {
- this(ptr, true, true);
+ this(ptr, true);
}
- public Initializer(Pointer ptr, boolean ownsRef, boolean ownsHandle) {
+ public Initializer(Pointer ptr, boolean ownsRef) {
if (ptr == null)
throw new RuntimeException("Invalid NULL pointer for initializer");
this.ptr = ptr;
this.ownsRef = ownsRef;
- this.ownsHandle = ownsHandle;
}
}
public Handle() {
}
- abstract protected void invalidate();
}
Modified: trunk/src/org/gnome/gir/gobject/NativeObject.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/NativeObject.java (original)
+++ trunk/src/org/gnome/gir/gobject/NativeObject.java Sun Nov 16 23:58:56 2008
@@ -53,6 +53,7 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.gnome.gir.gobject.GObjectAPI.GObjectStruct;
import org.gnome.gir.repository.BaseInfo;
import com.sun.jna.Pointer;
@@ -61,13 +62,10 @@
*
*/
public abstract class NativeObject extends Handle {
- private final AtomicBoolean disposed = new AtomicBoolean(false);
- private final AtomicBoolean valid = new AtomicBoolean(true);
private final Pointer handle;
- protected final AtomicBoolean ownsHandle = new AtomicBoolean(false);
private final NativeRef nativeRef;
- private static final ConcurrentMap<Pointer, NativeRef> instanceMap = new ConcurrentHashMap<Pointer, NativeRef>();
+ private static final ConcurrentMap<Pointer, NativeRef> instanceMap = new ConcurrentHashMap<Pointer, NativeRef>();
static class NativeRef extends WeakReference<NativeObject> {
public NativeRef(NativeObject obj) {
@@ -80,13 +78,13 @@
* they own the native object. Special cases can use the other constructor.
*/
protected static Initializer initializer(Pointer ptr) {
- return initializer(ptr, false, true);
+ return initializer(ptr, false);
}
- protected static Initializer initializer(Pointer ptr, boolean needRef, boolean ownsHandle) {
+ protected static Initializer initializer(Pointer ptr, boolean needRef) {
if (ptr == null) {
throw new IllegalArgumentException("Invalid native pointer");
}
- return new Initializer(ptr, needRef, ownsHandle);
+ return new Initializer(ptr, needRef);
}
/** Creates a new instance of NativeObject */
protected NativeObject(final Initializer init) {
@@ -95,7 +93,6 @@
}
nativeRef = new NativeRef(this);
this.handle = init.ptr;
- this.ownsHandle.set(init.ownsHandle);
//
// Only store this object in the map if we can tell when it has been disposed
@@ -108,149 +105,143 @@
}
}
-
- abstract protected void disposeNativeHandle(Pointer ptr);
-
- public void dispose() {
- if (!disposed.getAndSet(true)) {
- instanceMap.remove(handle, nativeRef);
- if (ownsHandle.get()) {
- disposeNativeHandle(handle);
- }
- valid.set(false);
- }
- }
-
- protected void invalidate() {
- instanceMap.remove(handle(), nativeRef);
- disposed.set(true);
- ownsHandle.set(false);
- valid.set(false);
- }
-
+
@Override
protected void finalize() throws Throwable {
- try {
- dispose();
- } finally {
- super.finalize();
- }
+ instanceMap.remove(handle, nativeRef);
+ super.finalize();
}
+
protected Object nativeValue() {
- return handle();
- }
- protected Pointer handle() {
- if (!valid.get()) {
- throw new IllegalStateException("Native object has been disposed");
- }
- return handle;
+ return getNativeAddress();
}
+
public Pointer getNativeAddress() {
return handle;
}
- protected boolean isDisposed() {
- return disposed.get();
- }
- protected static NativeObject instanceFor(Pointer ptr) {
- WeakReference<NativeObject> ref = instanceMap.get(ptr);
-
- //
- // If the reference was there, but the object it pointed to had been collected, remove it from the map
- //
- if (ref != null && ref.get() == null) {
- instanceMap.remove(ptr);
- }
- return ref != null ? ref.get() : null;
- }
- public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, boolean ownsRef) {
- return objectFor(ptr, cls, ownsRef, true);
- }
-
- private static Class<?> getStubClassFor(Class<?> proxyClass) {
- Class<?>[] declared = proxyClass.getDeclaredClasses();
- for (Class<?> c: declared) {
- if (c.getName().endsWith("$AnonStub"))
- return c;
- }
- throw new RuntimeException("Couldn't find Stub for interface: " + proxyClass);
- }
- public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, boolean ownsRef, boolean ownsHandle) {
- return objectFor(ptr, cls, ownsRef, ownsHandle, true);
- }
-
- @SuppressWarnings("unchecked")
- public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, boolean ownsRef, boolean ownsHandle, boolean peekGType) {
- // Ignore null pointers
- if (ptr == null) {
- return null;
- }
- NativeObject obj = null;
- if (BaseInfo.class.isAssignableFrom(cls))
- obj = BaseInfo.newInstanceFor(ptr);
- else if (GObject.class.isAssignableFrom(cls) || GObject.GObjectProxy.class.isAssignableFrom(cls))
- obj = NativeObject.instanceFor(ptr);
- if (obj != null && cls.isInstance(obj)) {
- if (ownsRef) {
- ((RefCountedObject) obj).unref(); // Lose the extra ref that we expect functions to add by default
- }
- return cls.cast(obj);
- }
-
+ public static class Internals {
- /* Special-case GObject.GObjectProxy here - these are interface values
- * for which we don't know of a current concrete class.
- */
- if (cls.isInterface() && GObject.GObjectProxy.class.isAssignableFrom(cls)) {
- cls = (Class<T>) getStubClassFor(cls);
+ public static final boolean debugMemory;
+
+ static {
+ debugMemory = System.getProperty("jgir.debugMemory") != null;
}
- /* For GObject, read the g_class field to find
- * the most exact class match
- */
- else if (peekGType && GObject.class.isAssignableFrom(cls)) {
- cls = classFor(ptr, cls);
- /* If it's abstract, pull out the stub */
- if ((cls.getModifiers() & Modifier.ABSTRACT) != 0)
- cls = (Class<T>) getStubClassFor(cls);
+
+ public static final void debugMemory(GObject obj, String fmt, Object... args) {
+ if (debugMemory) {
+ Object[] newArgs = new Object[args.length+2];
+ System.arraycopy(args, 0, newArgs, 1, args.length);
+ newArgs[0] = obj;
+ if (obj != null) {
+ GObjectStruct objStruct = new GObjectAPI.GObjectStruct(obj);
+ newArgs[newArgs.length-1] = objStruct.ref_count;
+ } else {
+ newArgs[newArgs.length-1] = "<null>";
+ }
+ System.err.println(String.format(fmt, newArgs));
+ }
}
- /* Ok, let's try to find an Initializer constructor
- */
- try {
- Constructor<T> constructor = cls.getDeclaredConstructor(Initializer.class);
- constructor.setAccessible(true);
- T retVal = constructor.newInstance(initializer(ptr, ownsRef, ownsHandle));
- //retVal.initNativeHandle(ptr, refAdjust > 0, ownsHandle);
- return retVal;
- } catch (SecurityException ex) {
- throw new RuntimeException(ex);
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
- } catch (InstantiationException ex) {
- throw new RuntimeException(ex);
- } catch (NoSuchMethodException ex) {
- throw new RuntimeException(ex);
- } catch (InvocationTargetException ex) {
- throw new RuntimeException(ex);
- }
-
+
+ protected static NativeObject instanceFor(Pointer ptr) {
+ WeakReference<NativeObject> ref = NativeObject.instanceMap.get(ptr);
+
+ //
+ // If the reference was there, but the object it pointed to had been collected, remove it from the map
+ //
+ if (ref != null && ref.get() == null) {
+ NativeObject.instanceMap.remove(ptr);
+ }
+ return ref != null ? ref.get() : null;
+ }
+
+ private static Class<?> getStubClassFor(Class<?> proxyClass) {
+ Class<?>[] declared = proxyClass.getDeclaredClasses();
+ for (Class<?> c: declared) {
+ if (c.getName().endsWith("$AnonStub"))
+ return c;
+ }
+ throw new RuntimeException("Couldn't find Stub for interface: " + proxyClass);
+ }
+
+ public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, boolean ownsRef) {
+ return objectFor(ptr, cls, ownsRef, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, boolean ownsRef, boolean peekGType) {
+ // Ignore null pointers
+ if (ptr == null) {
+ return null;
+ }
+ NativeObject obj = null;
+ if (BaseInfo.class.isAssignableFrom(cls))
+ obj = BaseInfo.newInstanceFor(ptr);
+ else if (GObject.class.isAssignableFrom(cls) || GObject.GObjectProxy.class.isAssignableFrom(cls))
+ obj = Internals.instanceFor(ptr);
+ if (obj != null && cls.isInstance(obj)) {
+ if (ownsRef) {
+ ((RefCountedObject) obj).unref(); // Lose the extra ref that we expect functions to add by default
+ }
+ return cls.cast(obj);
+ }
+
+
+ /* Special-case GObject.GObjectProxy here - these are interface values
+ * for which we don't know of a current concrete class.
+ */
+ if (cls.isInterface() && GObject.GObjectProxy.class.isAssignableFrom(cls)) {
+ cls = (Class<T>) Internals.getStubClassFor(cls);
+ }
+ /* For GObject, read the g_class field to find
+ * the most exact class match
+ */
+ else if (peekGType && GObject.class.isAssignableFrom(cls)) {
+ cls = classFor(ptr, cls);
+ /* If it's abstract, pull out the stub */
+ if ((cls.getModifiers() & Modifier.ABSTRACT) != 0)
+ cls = (Class<T>) Internals.getStubClassFor(cls);
+ }
+ /* Ok, let's try to find an Initializer constructor
+ */
+ try {
+ Constructor<T> constructor = cls.getDeclaredConstructor(Initializer.class);
+ constructor.setAccessible(true);
+ T retVal = constructor.newInstance(initializer(ptr, ownsRef));
+ //retVal.initNativeHandle(ptr, refAdjust > 0, ownsHandle);
+ return retVal;
+ } catch (SecurityException ex) {
+ throw new RuntimeException(ex);
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ } catch (InstantiationException ex) {
+ throw new RuntimeException(ex);
+ } catch (NoSuchMethodException ex) {
+ throw new RuntimeException(ex);
+ } catch (InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static Class<?> lookupProxyChain(GType gtype) {
+ Class<?> ret = null;
+ while (ret == null && !gtype.equals(GType.OBJECT)) {
+ ret = GType.lookupProxyClass(gtype);
+ gtype = gtype.getParent();
+ }
+ return ret;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static <T extends NativeObject> Class<T> classFor(Pointer ptr, Class<T> defaultClass) {
+ GType gtype = GType.objectPeekType(ptr);
+ Class<?> cls = lookupProxyChain(gtype);
+ return (cls != null && defaultClass.isAssignableFrom(cls)) ? (Class<T>) cls : defaultClass;
+ }
}
- @SuppressWarnings("unchecked")
- protected static Class<?> lookupProxyChain(GType gtype) {
- Class<?> ret = null;
- while (ret == null && !gtype.equals(GType.OBJECT)) {
- ret = GType.lookupProxyClass(gtype);
- gtype = gtype.getParent();
- }
- return ret;
- }
-
- @SuppressWarnings("unchecked")
- protected static <T extends NativeObject> Class<T> classFor(Pointer ptr, Class<T> defaultClass) {
- GType gtype = GType.objectPeekType(ptr);
- Class<?> cls = lookupProxyChain(gtype);
- return (cls != null && defaultClass.isAssignableFrom(cls)) ? (Class<T>) cls : defaultClass;
- }
@Override
public boolean equals(Object o) {
@@ -264,13 +255,6 @@
@Override
public String toString() {
- return getClass().getSimpleName() + "(" + handle() + ")";
- }
-
- //
- // No longer want to garbage collect this object
- //
- public void disown() {
- ownsHandle.set(false);
+ return getClass().getSimpleName() + "(" + getNativeAddress() + ")";
}
}
Modified: trunk/src/org/gnome/gir/gobject/RefCountedObject.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/RefCountedObject.java (original)
+++ trunk/src/org/gnome/gir/gobject/RefCountedObject.java Sun Nov 16 23:58:56 2008
@@ -53,11 +53,17 @@
/** Creates a new instance of RefCountedObject */
protected RefCountedObject(Initializer init) {
super(init);
- if (init.ownsHandle && init.ownsRef) {
+ if (!init.ownsRef) {
ref();
}
}
// overridden in subclasses
abstract protected void ref();
abstract protected void unref();
+
+ @Override
+ protected void finalize() throws Throwable {
+ unref();
+ super.finalize();
+ }
}
Modified: trunk/src/org/gnome/gir/repository/BaseInfo.java
==============================================================================
--- trunk/src/org/gnome/gir/repository/BaseInfo.java (original)
+++ trunk/src/org/gnome/gir/repository/BaseInfo.java Sun Nov 16 23:58:56 2008
@@ -18,7 +18,7 @@
String name = GIntrospectionAPI.gi.g_base_info_get_name(ptr);
throw new UnresolvedException(namespace, name);
}
- Initializer init = new Initializer(ptr, false, false);
+ Initializer init = new Initializer(ptr, true);
if (itype == InfoType.ENUM.ordinal())
return new EnumInfo(init);
if (itype == InfoType.FLAGS.ordinal())
@@ -43,7 +43,7 @@
return new PropertyInfo(init);
if (itype == InfoType.CONSTANT.ordinal())
return new ConstantInfo(init);
- return new BaseInfo(new Initializer(ptr));
+ return new BaseInfo(init);
}
@Override
@@ -58,18 +58,13 @@
public String getName() {
if (cachedName == null)
- cachedName = Repository.getNativeLibrary().g_base_info_get_name(this.handle());
+ cachedName = Repository.getNativeLibrary().g_base_info_get_name(getNativeAddress());
return cachedName;
}
- @Override
- protected void disposeNativeHandle(Pointer ptr) {
- unref();
- }
-
public String getNamespace() {
if (cachedNamespace == null)
- cachedNamespace = GIntrospectionAPI.gi.g_base_info_get_namespace(this.handle());
+ cachedNamespace = GIntrospectionAPI.gi.g_base_info_get_namespace(getNativeAddress());
return cachedNamespace;
}
Modified: trunk/src/org/gnome/gir/repository/Repository.java
==============================================================================
--- trunk/src/org/gnome/gir/repository/Repository.java (original)
+++ trunk/src/org/gnome/gir/repository/Repository.java Sun Nov 16 23:58:56 2008
@@ -87,8 +87,8 @@
public static synchronized Repository getDefault() {
GObjectGlobals.init();
- return (Repository) NativeObject.objectFor(getNativeLibrary().g_irepository_get_default(),
- Repository.class, false, true, false);
+ return (Repository) NativeObject.Internals.objectFor(getNativeLibrary().g_irepository_get_default(),
+ Repository.class, false, false);
}
public void unloadAll() {
Modified: trunk/stub-examples/Test.java
==============================================================================
--- trunk/stub-examples/Test.java (original)
+++ trunk/stub-examples/Test.java Sun Nov 16 23:58:56 2008
@@ -80,7 +80,7 @@
if (error.getValue() != null) {
throw new GErrorException(new GErrorStruct(error.getValue()));
}
- return (Test) NativeObject.objectFor(result, Test.class, false);
+ return (Test) NativeObject.Internals.objectFor(result, Test.class, false);
}
public static Test newWithFoo(String blah) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]