java-gobject-introspection r20 - in trunk/src/org/gnome/gir: compiler gobject
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r20 - in trunk/src/org/gnome/gir: compiler gobject
- Date: Wed, 3 Sep 2008 14:52:32 +0000 (UTC)
Author: walters
Date: Wed Sep 3 14:52:32 2008
New Revision: 20
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=20&view=rev
Log:
Nuke custom GObject signal marshaling code; use Callback directly
Modified:
trunk/src/org/gnome/gir/compiler/CodeFactory.java
trunk/src/org/gnome/gir/compiler/Test.java
trunk/src/org/gnome/gir/gobject/GObject.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 Wed Sep 3 14:52:32 2008
@@ -851,10 +851,11 @@
compilation.writer.visitInnerClass(sigCompilation.internalName, compilation.internalName, sigClass,
ACC_PUBLIC + ACC_ABSTRACT + ACC_STATIC + ACC_INTERFACE);
sigCompilation.writer.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE,
- sigCompilation.internalName, null, "java/lang/Object", new String[] { "org/gnome/gir/gobject/Closure" });
+ sigCompilation.internalName, null, "java/lang/Object", new String[] { "com/sun/jna/Callback" });
sigCompilation.writer.visitInnerClass(sigCompilation.internalName, compilation.internalName,
sigClass, ACC_PUBLIC + ACC_STATIC + ACC_ABSTRACT + ACC_INTERFACE);
+ writeJnaCallbackTypeMapper(sigCompilation);
/* public static final String METHOD_NAME = */
FieldVisitor fv = sigCompilation.writer.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC,
@@ -873,7 +874,7 @@
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(rawSigName);
mv.visitVarInsn(ALOAD, 1);
- mv.visitMethodInsn(INVOKEVIRTUAL, compilation.internalName, "connect", "(Ljava/lang/String;Lorg/gnome/gir/gobject/Closure;)J");
+ mv.visitMethodInsn(INVOKEVIRTUAL, compilation.internalName, "connect", "(Ljava/lang/String;Lcom/sun/jna/Callback;)J");
mv.visitInsn(LRETURN);
Label l1 = new Label();
mv.visitLabel(l1);
@@ -1342,20 +1343,11 @@
compilation.close();
}
- private void compile(CallbackInfo info) {
- MethodVisitor mv;
- ClassCompilation compilation = getCompilation(info);
-
- String internalName = getInternalName(info);
- compilation.writer.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, internalName, null, "java/lang/Object",
- new String[] { "com/sun/jna/Callback" });
-
- CallableCompilationContext ctx = tryCompileCallable(info);
-
+ private void writeJnaCallbackTypeMapper(ClassCompilation compilation) {
FieldVisitor fv = compilation.writer.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, "TYPE_MAPPER", "Lcom/sun/jna/TypeMapper;", null, null);
fv.visitEnd();
- mv = compilation.writer.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+ MethodVisitor mv = compilation.writer.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
@@ -1366,6 +1358,19 @@
mv.visitInsn(RETURN);
mv.visitMaxs(1, 0);
mv.visitEnd();
+ }
+
+ private void compile(CallbackInfo info) {
+ MethodVisitor mv;
+ ClassCompilation compilation = getCompilation(info);
+
+ String internalName = getInternalName(info);
+ compilation.writer.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, internalName, null, "java/lang/Object",
+ new String[] { "com/sun/jna/Callback" });
+
+ CallableCompilationContext ctx = tryCompileCallable(info);
+
+ writeJnaCallbackTypeMapper(compilation);
if (ctx != null) {
String descriptor = Type.getMethodDescriptor(ctx.returnType, ctx.argTypes.toArray(new Type[0]));
Modified: trunk/src/org/gnome/gir/compiler/Test.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/Test.java (original)
+++ trunk/src/org/gnome/gir/compiler/Test.java Wed Sep 3 14:52:32 2008
@@ -3,7 +3,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.gnome.gir.gobject.Closure;
import org.gnome.gir.gobject.GErrorException;
import org.gnome.gir.gobject.GErrorStruct;
import org.gnome.gir.gobject.GObject;
@@ -13,6 +12,7 @@
import org.gnome.gir.repository.Direction;
import org.gnome.gir.repository.Repository;
+import com.sun.jna.Callback;
import com.sun.jna.Function;
import com.sun.jna.Library;
import com.sun.jna.NativeLibrary;
@@ -56,7 +56,7 @@
.invoke(Pointer.class, new Object[] { dir, foo, blah }, Internals.invocationOptions)));
}
- public interface Clicked extends Closure {
+ public interface Clicked extends Callback {
public static final String METHOD_NAME = "onClicked";
public void onClicked(Test t);
}
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 Wed Sep 3 14:52:32 2008
@@ -45,7 +45,6 @@
package org.gnome.gir.gobject;
-import java.lang.reflect.Method;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
@@ -57,8 +56,6 @@
import com.sun.jna.Callback;
import com.sun.jna.NativeLong;
-import com.sun.jna.NativeMapped;
-import com.sun.jna.NativeMappedConverter;
import com.sun.jna.Pointer;
/**
@@ -67,12 +64,11 @@
*/
public abstract class GObject extends RefCountedObject {
private static final Map<GObject, Boolean> strongReferences = new ConcurrentHashMap<GObject, Boolean>();
-
- private Map<Class<?>, Map<Object, SignalCallback>> signalListeners;
- private Map<String, Map<Closure, ClosureProxy>> signalClosures;
-
+
private final IntPtr objectID = new IntPtr(System.identityHashCode(this));
+ private Map<Long,Callback> signalHandlers = new HashMap<Long, Callback>();
+
/**
* A tagging interface used in the code generator - if a method returns an interface,
* we have it extend this interface so we know it's a GObject.
@@ -386,212 +382,24 @@
protected NativeLong g_signal_connect(String signal, Callback callback) {
return GObjectAPI.gobj.g_signal_connect_data(this, signal, callback, null, null, 0);
}
- private class SignalCallback {
-
- protected SignalCallback(String signal, Callback cb) {
- this.cb = cb;
- id = g_signal_connect(signal, cb);
- if (id.intValue() == 0) {
- throw new IllegalArgumentException(String.format("Failed to connect signal '%s'", signal));
- }
- }
- synchronized protected void disconnect() {
- if (id != null && id.intValue() != 0) {
- GObjectAPI.gobj.g_signal_handler_disconnect(GObject.this, id);
- id = null;
- }
- }
- protected void finalize() {
- // Ensure the native callback is removed
- disconnect();
- }
- Callback cb;
- NativeLong id;
- }
- private synchronized final Map<Class<?>, Map<Object, SignalCallback>> getListenerMap() {
- if (signalListeners == null) {
- signalListeners = new ConcurrentHashMap<Class<?>, Map<Object, SignalCallback>>();
- }
- return signalListeners;
- }
- private synchronized final Map<String, Map<Closure, ClosureProxy>> getClosureMap() {
- if (signalClosures == null) {
- signalClosures = new ConcurrentHashMap<String, Map<Closure, ClosureProxy>>();
- }
- return signalClosures;
- }
-
- public <T> void connect(Class<T> listenerClass, T listener, Callback cb) {
- String signal = listenerClass.getSimpleName().toLowerCase().replaceAll("_", "-");
- connect(signal, listenerClass, listener, cb);
- }
-
- public synchronized <T> void connect(String signal, Class<T> listenerClass, T listener, Callback cb) {
- final Map<Class<?>, Map<Object, SignalCallback>> signals = getListenerMap();
- Map<Object, SignalCallback> m = signals.get(listenerClass);
- if (m == null) {
- m = new HashMap<Object, SignalCallback>();
- signals.put(listenerClass, m);
- }
- m.put(listener, new SignalCallback(signal, cb));
- }
-
- public synchronized <T> void disconnect(Class<T> listenerClass, T listener) {
- final Map<Class<?>, Map<Object, SignalCallback>> signals = getListenerMap();
- Map<Object, SignalCallback> map = signals.get(listenerClass);
- if (map != null) {
- SignalCallback cb = map.remove(listener);
- if (cb != null) {
- cb.disconnect();
- }
- if (map.isEmpty()) {
- signals.remove(listenerClass);
- if (signalListeners.isEmpty()) {
- signalListeners = null;
- }
- }
- }
- }
- private final class ClosureProxy implements GSignalAPI.GSignalCallbackProxy {
- private final Closure closure;
- @SuppressWarnings("unused")
- private final String signal;
- private final Method method;
- private final Class<?>[] parameterTypes;
- NativeLong id;
-
- protected ClosureProxy(String signal, Closure closure) {
- this.closure = closure;
- this.signal = signal;
- Method invoke = null;
- for (Method m : closure.getClass().getDeclaredMethods()) {
- if (m.getName().startsWith("on")) {
- invoke = m;
- break;
- }
- }
- if (invoke == null) {
- throw new IllegalArgumentException(closure.getClass()
- + " does not have an invoke method");
- }
- invoke.setAccessible(true);
- this.method = invoke;
- //
- // The closure does not have a 'user_data' pointer, so push it in as the
- // last arg. The last arg will be dropped later in callback()
- //
- parameterTypes = new Class[method.getParameterTypes().length + 1];
- parameterTypes[parameterTypes.length - 1] = Pointer.class;
- for (int i = 0; i < method.getParameterTypes().length; ++i) {
- Class<?> paramType = method.getParameterTypes()[i];
- Class<?> nativeType = paramType;
- if (NativeObject.class.isAssignableFrom(paramType)) {
- nativeType = Pointer.class;
- } else if (Enum.class.isAssignableFrom(paramType)) {
- nativeType = int.class;
- } else if (String.class.isAssignableFrom(paramType)) {
- nativeType = Pointer.class;
- } else if (Boolean.class.isAssignableFrom(paramType)) {
- nativeType = int.class;
- }
- parameterTypes[i] = nativeType;
- }
- NativeLong connectID = GSignalAPI.gsignal.g_signal_connect_data(GObject.this,
- signal, this, null, null, 0);
- if (connectID.intValue() == 0) {
- throw new IllegalArgumentException(String.format("Failed to connect signal '%s'", signal));
- }
- this.id = connectID;
- }
- synchronized protected void disconnect() {
- if (id != null && id.intValue() != 0) {
- GObjectAPI.gobj.g_signal_handler_disconnect(GObject.this, id);
- id = null;
- }
- }
- @Override
- protected void finalize() {
- // Ensure the native callback is removed
- disconnect();
- }
- @SuppressWarnings("unchecked")
- public Object callback(Object[] parameters) {
-
- try {
- // Drop the last arg - it is the 'user_data' pointer
- Object[] methodParameters = new Object[parameters.length - 1];
-
- for (int i = 0; i < methodParameters.length; ++i) {
- Class paramType = method.getParameterTypes()[i];
- Object nativeParam = parameters[i];
- Object javaParam = nativeParam;
- if (nativeParam == null) {
- continue;
- }
-
- if (NativeObject.class.isAssignableFrom(paramType)) {
- javaParam = NativeObject.objectFor((Pointer) nativeParam,
- paramType, 1, true);
- } else if (Enum.class.isAssignableFrom(paramType)) {
- javaParam = EnumMapper.getInstance().valueOf((Integer) nativeParam,
- paramType);
- } else if (String.class.isAssignableFrom(paramType)) {
- javaParam = ((Pointer) nativeParam).getString(0);
- } else if (Boolean.class.isAssignableFrom(paramType)) {
- javaParam = Boolean.valueOf(((Integer) nativeParam).intValue() != 0);
- } else if (NativeMapped.class.isAssignableFrom(paramType)) {
- javaParam = NativeMappedConverter.getInstance(paramType).fromNative(nativeParam, null);
- } else {
- javaParam = nativeParam;
- }
- methodParameters[i] = javaParam;
- }
-
- return method.invoke(closure, methodParameters);
- } catch (Throwable t) {
- System.err.println("Signal invocation failed");
- t.printStackTrace();
- return Integer.valueOf(0);
- }
- }
-
- public Class<?>[] getParameterTypes() {
- return parameterTypes;
- }
-
- public Class<?> getReturnType() {
- return method.getReturnType();
- }
- }
- public synchronized long connect(String signal, Closure closure) {
- final Map<String, Map<Closure, ClosureProxy>> signals = getClosureMap();
- Map<Closure, ClosureProxy> m = signals.get(signal);
- if (m == null) {
- m = new HashMap<Closure, ClosureProxy>();
- signals.put(signal, m);
- }
- ClosureProxy cp = new ClosureProxy(signal, closure);
- m.put(closure, cp);
- return cp.id.longValue();
- }
- public synchronized void disconnect(String signal, Closure closure) {
- final Map<String, Map<Closure, ClosureProxy>> signals = signalClosures;
- if (signals == null) {
- return;
- }
- Map<Closure, ClosureProxy> map = signals.get(signal);
- if (map != null) {
- ClosureProxy cb = map.remove(signal);
- if (cb != null) {
- cb.disconnect();
- }
- if (map.isEmpty()) {
- signals.remove(signal);
- if (signalClosures.isEmpty()) {
- signalClosures = null;
- }
- }
- }
+
+ public synchronized long connect(String signal, Callback closure) {
+ NativeLong connectID = GSignalAPI.gsignal.g_signal_connect_data(GObject.this,
+ signal, closure, null, null, 0);
+ if (connectID.intValue() == 0) {
+ throw new IllegalArgumentException(String.format("Failed to connect signal '%s'", signal));
+ }
+ long id = connectID.longValue();
+ signalHandlers.put(id, closure);
+ return id;
+ }
+
+ public synchronized void disconnect(String signal, long id) {
+ Callback cb = signalHandlers.get(id);
+ if (cb == null)
+ throw new IllegalArgumentException("Invalid signal handler id:" + id);
+ GSignalAPI.gsignal.g_signal_handler_disconnect(GObject.this, new NativeLong(id));
+ signalHandlers.remove(id);
}
public static GObject objectFor(Pointer ptr, Class<? extends GObject> defaultClass) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]