java-gobject-introspection r158 - in trunk/src: gobject/internals gobject/runtime org/gnome/gir/compiler



Author: walters
Date: Sun Jan  4 03:22:55 2009
New Revision: 158
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=158&view=rev

Log:
Handle Gio.AsyncReadyCallback specially by keeping a ref until it's called

The way Gio works is that instead of GDestroyNotify, a
Gio.AsyncReadyCallback is guaranteed to be called exactly once.
Thus, we need to special case it in CodeFactory by creating a proxy
wrapper which holds a strong reference until the callback is invoked.

Added:
   trunk/src/gobject/internals/GioAPI.java
   trunk/src/gobject/runtime/AsyncReadyCallback.java
   trunk/src/gobject/runtime/AsyncResult.java
Modified:
   trunk/src/gobject/internals/GlibRuntime.java
   trunk/src/gobject/runtime/GType.java
   trunk/src/org/gnome/gir/compiler/CodeFactory.java
   trunk/src/org/gnome/gir/compiler/TypeMap.java

Added: trunk/src/gobject/internals/GioAPI.java
==============================================================================
--- (empty file)
+++ trunk/src/gobject/internals/GioAPI.java	Sun Jan  4 03:22:55 2009
@@ -0,0 +1,67 @@
+
+/* 
+ * Copyright (c) 2008 Colin Walters <walters verbum org>
+ * 
+ * This file is part of java-gobject-introspection.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
+ * Boston, MA  02111-1307  USA.
+ *
+ */
+/* 
+ * Copyright (c) 2007 Wayne Meissner
+ * 
+ * This file was originally part of gstreamer-java; modified for use in
+ * jgir.  By permission of author, this file has been relicensed from LGPLv3
+ * to the license of jgir; see below.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
+ * Boston, MA  02111-1307  USA. 
+ */
+
+package gobject.internals;
+
+import gobject.runtime.AsyncResult;
+import gobject.runtime.GObject;
+
+import java.util.HashMap;
+
+import com.sun.jna.Library;
+
+/**
+ *
+ */
+public interface GioAPI extends Library {
+    static GioAPI gio = GNative.loadLibrary("gio-2.0", GioAPI.class, new HashMap<String, Object>() {
+		private static final long serialVersionUID = 1L;
+		{
+			put(Library.OPTION_TYPE_MAPPER, new GTypeMapper());
+		}
+	});
+    
+    GObject g_async_result_get_source_object (AsyncResult result);
+}

Modified: trunk/src/gobject/internals/GlibRuntime.java
==============================================================================
--- trunk/src/gobject/internals/GlibRuntime.java	(original)
+++ trunk/src/gobject/internals/GlibRuntime.java	Sun Jan  4 03:22:55 2009
@@ -22,6 +22,8 @@
 
 package gobject.internals;
 
+import gobject.runtime.AsyncReadyCallback;
+import gobject.runtime.AsyncResult;
 import gobject.runtime.GObject;
 
 import java.util.ArrayList;
@@ -47,7 +49,10 @@
 	 */
 	private static final Set<CallbackData> outstandingCallbacks 
 		= Collections.synchronizedSet(new HashSet<CallbackData>());
-
+	
+	/* This one holds async callbacks, which are just called once */
+	private static final Set<AsyncReadyCallback> outstandingAsync 
+		= Collections.synchronizedSet(new HashSet<AsyncReadyCallback>());
 	
 	private static AtomicBoolean initialized = new AtomicBoolean(false);
 	
@@ -98,6 +103,21 @@
 		return destroy;
 	}
 	
+	public static final AsyncReadyCallback createAsyncReadyProxy(final AsyncReadyCallback callback) {
+		if (callback == null)
+			return null;
+		
+		AsyncReadyCallback proxy = new AsyncReadyCallback() {
+			@Override
+			public void callback(GObject object, AsyncResult result) {
+				outstandingAsync.remove(callback);
+				callback.callback(object, result);
+			}
+		};
+		outstandingAsync.add(proxy);
+		return proxy;
+	}
+	
 	public static List<String> convertListUtf8(GenericGList glist, Transfer transfer) {
 		List<String> ret = new ArrayList<String>();
 		GenericGList origList = glist;

Added: trunk/src/gobject/runtime/AsyncReadyCallback.java
==============================================================================
--- (empty file)
+++ trunk/src/gobject/runtime/AsyncReadyCallback.java	Sun Jan  4 03:22:55 2009
@@ -0,0 +1,16 @@
+package gobject.runtime;
+
+import gobject.internals.GTypeMapper;
+
+import com.sun.jna.Callback;
+import com.sun.jna.TypeMapper;
+
+/**
+ * Type definition for a function that will be called back 
+ * when an asynchronous operation within GIO has been completed.
+ */
+public interface AsyncReadyCallback extends Callback {
+	final TypeMapper TYPE_MAPPER = GTypeMapper.getInstance();
+	
+	public void callback(GObject object, AsyncResult result);
+}

Added: trunk/src/gobject/runtime/AsyncResult.java
==============================================================================
--- (empty file)
+++ trunk/src/gobject/runtime/AsyncResult.java	Sun Jan  4 03:22:55 2009
@@ -0,0 +1,18 @@
+package gobject.runtime;
+
+import gobject.internals.GioAPI;
+import gobject.runtime.GObject.GObjectProxy;
+
+
+/**
+ * Provides a base class for implementing asynchronous function results. 
+ */
+public interface AsyncResult extends GObjectProxy {
+	public GObject getSourceObject();
+	
+	public static final class AnonStub implements AsyncResult {
+		public GObject getSourceObject() {
+			return GioAPI.gio.g_async_result_get_source_object(this);			
+		}
+	}
+}

Modified: trunk/src/gobject/runtime/GType.java
==============================================================================
--- trunk/src/gobject/runtime/GType.java	(original)
+++ trunk/src/gobject/runtime/GType.java	Sun Jan  4 03:22:55 2009
@@ -149,11 +149,20 @@
 			for (String unmapped : gobjectIntegerUnmapped)
 				put("GObject." + unmapped, "java/lang/Integer");
 
+			put("Gio.AsyncReadyCallback", runtimeNamespace + "AsyncReadyCallback");
+			put("Gio.AsyncResult", runtimeNamespace + "AsyncResult");			
+			
 			for (String name : new String[] { "Context" }) {
 				put("Cairo." + name, internalsNamespace + "UnmappedPointer");
 			}
 		}
 	};
+	
+	public static boolean isMapped(String namespace, String name) {
+		String key = namespace + "." + name;
+		String val = GType.overrides.get(key);
+		return val != null;
+	}
 
 	public static String getInternalNameMapped(String namespace, String name) {
 		String key = namespace + "." + name;

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 Jan  4 03:22:55 2009
@@ -53,6 +53,7 @@
 import gobject.internals.NativeEnum;
 import gobject.internals.NativeObject;
 import gobject.internals.RegisteredType;
+import gobject.runtime.AsyncReadyCallback;
 import gobject.runtime.GBoxed;
 import gobject.runtime.GErrorException;
 import gobject.runtime.GFlags;
@@ -193,6 +194,10 @@
 	static String getInternalNameMapped(BaseInfo info) {
 		return GType.getInternalNameMapped(info.getNamespace(), info.getName());
 	}
+	
+	private static boolean isMapped(BaseInfo info) {
+		return GType.isMapped(info.getNamespace(), info.getName());
+	}
 
 	private static boolean requiresConversion(TypeInfo info, Transfer transfer) {
 		return writeConversionToJava(null, null, info, transfer);
@@ -1132,6 +1137,7 @@
 		Map<Integer, Integer> lengthOfArrayIndices = new HashMap<Integer, Integer>();
 		Map<Integer, Integer> arrayToLengthIndices = new HashMap<Integer, Integer>();
 		Set<Integer> userDataIndices = new HashSet<Integer>();
+		Set<Integer> asyncReadyCallbackIndices = new HashSet<Integer>();
 		Map<Integer, Integer> destroyNotifyIndices = new HashMap<Integer, Integer>();
 
 		public CallableCompilationContext() {
@@ -1249,6 +1255,8 @@
 				}
 				ctx.destroyNotifyIndices.put(argOffset, firstSeenCallback);
 				continue;
+			} else if (TypeMap.isAsyncReadyCallback(arg)) {
+				ctx.asyncReadyCallbackIndices.add(argOffset);
 			} else if (arg.getDirection() == Direction.IN && info.getTag().equals(TypeTag.INTERFACE)
 					&& info.getInterface() instanceof CallbackInfo) {
 				if (firstSeenCallback >= 0) {
@@ -1372,7 +1380,14 @@
 			Integer arraySource = ctx.lengthOfArrayIndices.get(i);
 			Integer lengthOfArray = ctx.arrayToLengthIndices.get(i);
 			Integer callbackIdx = ctx.destroyNotifyIndices.get(i);
-			if (arraySource != null) {
+			if (ctx.asyncReadyCallbackIndices.contains(i)) {
+				int offset = ctx.argOffsetToApi(i);
+				LocalVariable var = locals.get(offset);
+				var.writeLoadArgument(mv);
+				mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(GlibRuntime.class), "createAsyncReadyProxy", Type
+						.getMethodDescriptor(getType(AsyncReadyCallback.class),
+								new Type[] { getType(AsyncReadyCallback.class) }));				
+			} else if (arraySource != null) {
 				ArgInfo source = ctx.args[arraySource - (ctx.isMethod ? 1 : 0)];
 				assert source.getType().getTag().equals(TypeTag.ARRAY);
 				int offset = ctx.argOffsetToApi(arraySource);
@@ -1871,6 +1886,8 @@
 		BaseInfo[] infos = repo.getInfos(namespace);
 		Set<String> globalSigs = new HashSet<String>();
 		for (BaseInfo baseInfo : infos) {
+			if (isMapped(baseInfo))
+				continue;
 			logger.fine("Compiling " + baseInfo);
 			if (baseInfo instanceof EnumInfo) {
 				compile((EnumInfo) baseInfo);

Modified: trunk/src/org/gnome/gir/compiler/TypeMap.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/TypeMap.java	(original)
+++ trunk/src/org/gnome/gir/compiler/TypeMap.java	Sun Jan  4 03:22:55 2009
@@ -311,6 +311,14 @@
 			return iface.getName().equals("DestroyNotify");
 		return false;
 	}
+	
+	public static boolean isAsyncReadyCallback(ArgInfo arg) {
+		TypeInfo type = arg.getType();
+		if (!type.getTag().equals(TypeTag.INTERFACE))
+			return false;
+		BaseInfo iface = type.getInterface();
+		return iface.getNamespace().equals("Gio") && iface.getName().equals("AsyncReadyCallback");
+	}
 
 	static String getUniqueSignature(String name, Type returnType, List<Type> args) {
 		StringBuilder builder = new StringBuilder(name);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]