[Kde-bindings] playground/bindings/kimono

Richard Dale Richard_Dale at tipitina.demon.co.uk
Thu Feb 8 18:07:04 UTC 2007


SVN commit 631668 by rdale:

* Added a first attempt at setting up the strongReferenceMap and calling
  destructors. A boolean function CreateStrongReference() checks whether
  or not a strong reference is needed when a new instance has been
  constructed. Another function is needed to checked whether the C++
  instance still has a parent or container, and not delete if it has.

* Currently apps crash on exit, but the Qyoto.DeleteQApp()
  hack shouldn't be need anymore once destructors are working.

CCMAIL: kde-bindings at kde.org



 M  +11 -0     ChangeLog  
 M  +16 -7     SmokeInvocation.cs  
 M  +29 -9     SmokeMarshallers.cs  
 M  +42 -0     handlers.cpp  
 M  +8 -4      qyoto.cpp  
 M  +2 -0      qyoto.h  


--- trunk/playground/bindings/kimono/ChangeLog #631667:631668
@@ -1,3 +1,14 @@
+2007-02-08  Richard Dale  <rdale at foton.es>
+
+	* Added a first attempt at setting up the strongReferenceMap and calling
+	  destructors. A boolean function CreateStrongReference() checks whether
+	  or not a strong reference is needed when a new instance has been
+	  constructed. Another function is needed to checked whether the C++
+	  instance still has a parent or container, and not delete if it has.
+
+	* Currently apps crash on exit, but the Qyoto.DeleteQApp()
+	  hack shouldn't be need anymore once destructors are working.
+
 2007-02-08  Arno Rehn  <arno at arnorehn.de>
 
 	* Fixed names of flags in Qyoto.cs
--- trunk/playground/bindings/kimono/SmokeInvocation.cs #631667:631668
@@ -374,15 +374,24 @@
 
 			IMethodReturnMessage returnMessage = (IMethodReturnMessage) message;
 
-			// Ignore destructors for now until a way of coordinating C# GC
-			// with C++ deletions has been implemented
-			if (	!((SmokeMethod) smokeMethod[0]).MungedName.StartsWith("~")
-					|| (_className == "QApplication" && ((SmokeMethod) smokeMethod[0]).MungedName == "~QApplication")
-					|| (_className == "QCoreApplication" && ((SmokeMethod) smokeMethod[0]).MungedName == "~QCoreApplication") )
+			// Ignore destructors where the destructor method isn't the actual class
+			// of the instance
+			if (	(	((SmokeMethod) smokeMethod[0]).MungedName.StartsWith("~")
+						&& (("~" + _className) != ((SmokeMethod) smokeMethod[0]).MungedName) )
+					|| ((SmokeMethod) smokeMethod[0]).MungedName == "~QMetaObject" )
 			{
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_TRANSPARENT_PROXY) != 0) {
+					Console.WriteLine(	"SKIPPING Invoke() MethodName: {0}.{1} Type: {2} ArgCount: {3}", 
+										_className,
+										callMessage.MethodName, 
+										callMessage.TypeName, 
+										callMessage.ArgCount.ToString() );
+				}
+#endif
+				return returnMessage;
+			} else {
 				;
-			} else {
-				return returnMessage;
 			}
 
 			if (methodId == -1) {
--- trunk/playground/bindings/kimono/SmokeMarshallers.cs #631667:631668
@@ -1,3 +1,5 @@
+#define DEBUG
+
 namespace Qyoto {
 	using System;
 	using System.Collections;
@@ -62,7 +64,7 @@
 		public static extern void InstallSetSmokeObject(SetIntPtr callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
-		public static extern void InstallMapPointer(SetIntPtr callback);
+		public static extern void InstallMapPointer(MapPointerFn callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
 		public static extern void InstallUnmapPointer(FromIntPtr callback);
@@ -142,6 +144,7 @@
 		public delegate IntPtr GetIntPtr(IntPtr instance);
 		public delegate void SetIntPtr(IntPtr instance, IntPtr ptr);
 		public delegate void FromIntPtr(IntPtr ptr);
+		public delegate void MapPointerFn(IntPtr instance, IntPtr ptr, bool createStrongReference);
 		public delegate IntPtr CreateInstanceFn(string className);
 		public delegate void InvokeCustomSlotFn(IntPtr obj, string slot, IntPtr stack, IntPtr ret);
 		public delegate bool IsSmokeClassFn(IntPtr obj);
@@ -211,10 +214,23 @@
 		// and the value is a WeakReference to the C# instance.
 		static private Dictionary<IntPtr, WeakReference> pointerMap = new Dictionary<IntPtr, WeakReference>();
 
-		public static void MapPointer(IntPtr ptr, IntPtr instancePtr) {
+		public static void MapPointer(IntPtr ptr, IntPtr instancePtr, bool createStrongReference) {
 			Object instance = ((GCHandle) instancePtr).Target;
 			WeakReference weakRef = new WeakReference(instance);
 			pointerMap[ptr] = weakRef;
+#if DEBUG
+			if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+				Console.WriteLine("MapPointer() Creating weak reference {0} to ptr: {1}", instance, ptr);
+			}
+#endif
+			if (createStrongReference) {
+				strongReferenceMap[ptr] = instance;
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("MapPointer() Creating strong reference {0} to ptr: {1}", instance, ptr);
+				}
+#endif
+			}
 		}
 		
 		public static void UnmapPointer(IntPtr ptr) {
@@ -222,9 +238,9 @@
 			if (!strongReferenceMap.ContainsKey(ptr)) {
 #if DEBUG
 				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
-					object ref;
-					if (strongReferenceMap.TryGetValue(ptr, out ref)) {
-						Console.WriteLine("UnmapPointer() Removing strong reference {0} to ptr: {1}", ref, ptr);
+					object reference;
+					if (strongReferenceMap.TryGetValue(ptr, out reference)) {
+						Console.WriteLine("UnmapPointer() Removing strong reference {0} to ptr: {1}", reference, ptr);
 					}
 				}
 #endif
@@ -286,7 +302,9 @@
 		public static IntPtr CreateInstance(string className) {
 			Type klass = Type.GetType(className);
 #if DEBUG
-			Console.WriteLine("ENTER CreateInstance className => {0}, {1}", className, klass);
+			if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+				Console.WriteLine("ENTER CreateInstance className => {0}, {1}", className, klass);
+			}
 #endif
 
 			Type[] constructorParamTypes = new Type[1];
@@ -299,14 +317,16 @@
 			}
 			object result = constructorInfo.Invoke(new object [] { constructorParamTypes[0] });
 #if DEBUG
-			Console.WriteLine("CreateInstance(\"{0}\") constructed {1}", className, result);
+			if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+				Console.WriteLine("CreateInstance(\"{0}\") constructed {1}", className, result);
+			}
 #endif
 			Type[] paramTypes = new Type[0];
 			MethodInfo proxyCreator = klass.GetMethod("CreateProxy", BindingFlags.NonPublic 
 																	| BindingFlags.Instance
 																	| BindingFlags.DeclaredOnly);
 			if (proxyCreator == null) {
-				Console.WriteLine("CreateInstance() proxyCreator method missing");
+				Console.Error.WriteLine("CreateInstance() proxyCreator method missing");
 				return (IntPtr) 0;
 			}
 			proxyCreator.Invoke(result, null);
@@ -458,7 +478,7 @@
 		static private GetIntPtr getSmokeObject = new GetIntPtr(GetSmokeObject);
 		static private SetIntPtr setSmokeObject = new SetIntPtr(SetSmokeObject);
 		
-		static private SetIntPtr mapPointer = new SetIntPtr(MapPointer);
+		static private MapPointerFn mapPointer = new MapPointerFn(MapPointer);
 		static private FromIntPtr unmapPointer = new FromIntPtr(UnmapPointer);
 		static private GetIntPtr getPointerObject = new GetIntPtr(GetPointerObject);
 		
--- trunk/playground/bindings/kimono/handlers.cpp #631667:631668
@@ -225,6 +225,48 @@
 extern bool isDerivedFromByName(Smoke *smoke, const char *className, const char *baseClassName);
 extern void mapPointer(void * obj, smokeqyoto_object *o, Smoke::Index classId, void *lastptr);
 
+bool
+CreateStrongReference(smokeqyoto_object *o)
+{
+    const char *className = o->smoke->classes[o->classId].className;
+		
+	if (	qstrcmp(className, "QObject") == 0
+			|| qstrcmp(className, "QListBoxItem") == 0
+			|| qstrcmp(className, "QStyleSheetItem") == 0
+			|| qstrcmp(className, "QSqlCursor") == 0
+			|| qstrcmp(className, "QModelIndex") == 0 )
+	{
+		return true;
+	} else if (isDerivedFromByName(o->smoke, className, "QLayoutItem")) {
+		QLayoutItem * item = (QLayoutItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QLayoutItem"));
+		if (item->layout() != 0 || item->widget() != 0 || item->spacerItem() != 0) {
+			return true;
+		}
+	} else if (qstrcmp(className, "QListWidgetItem") == 0) {
+		QListWidgetItem * item = (QListWidgetItem *) o->ptr;
+		if (item->listWidget() != 0) {
+			return true;
+		}
+	} else if (isDerivedFromByName(o->smoke, className, "QTableWidgetItem")) {
+		QTableWidgetItem * item = (QTableWidgetItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QTableWidgetItem"));
+		if (item->tableWidget() != 0) {
+			return true;
+		}
+	} else if (isDerivedFromByName(o->smoke, className, "QWidget")) {
+		QWidget * qwidget = (QWidget *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QWidget"));
+		if (qwidget->parentWidget() != 0) {
+			return true;
+		}
+	} else if (isDerivedFromByName(o->smoke, className, "QObject")) {
+		QObject * qobject = (QObject *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QObject"));
+		if (qobject->parent() != 0) {
+			return true;
+		}
+	}
+	
+    return false;
+}
+
 /*
  * Given an approximate classname and a qt instance, try to improve the resolution of the name
  * by using the various Qt rtti mechanisms for QObjects, QEvents and QCanvasItems
--- trunk/playground/bindings/kimono/qyoto.cpp #631667:631668
@@ -68,7 +68,7 @@
 static GetIntPtr GetSmokeObject;
 static SetIntPtr SetSmokeObject;
 
-static SetIntPtr MapPointer;
+static MapPointerFn MapPointer;
 static FromIntPtr UnmapPointer;
 static GetIntPtr GetPointerObject;
 
@@ -352,9 +352,13 @@
 		lastptr = ptr;
 		if (do_debug & qtdb_gc) {
 			const char *className = o->smoke->classes[o->classId].className;
-			qWarning("mapPointer (%s*)%p -> %p", className, ptr, (void*)obj);
+			qWarning(	"mapPointer (%s*)%p -> %p strong ref: %s", 
+						className, 
+						ptr, 
+						(void*)obj,
+						CreateStrongReference(o) ? "true" : "false" );
 		}
-		(*MapPointer)(ptr, obj);
+		(*MapPointer)(ptr, obj, CreateStrongReference(o));
     }
 	
 	for (Smoke::Index *i = o->smoke->inheritanceList + o->smoke->classes[classId].parents; *i; i++) {
@@ -1153,7 +1157,7 @@
 }
 
 void 
-InstallMapPointer(SetIntPtr callback)
+InstallMapPointer(MapPointerFn callback)
 {
 	MapPointer = callback;
 }
--- trunk/playground/bindings/kimono/qyoto.h #631667:631668
@@ -58,6 +58,7 @@
 void unmapPointer(smokeqyoto_object *, Smoke::Index, void*);
 smokeqyoto_object *value_obj_info(void * value);
 void * getPointerObject(void *ptr);
+bool CreateStrongReference(smokeqyoto_object *o);
 
 typedef void* (*NoArgs)();
 typedef void* (*GetIntPtr)(void *);
@@ -66,6 +67,7 @@
 typedef void* (*GetIntPtrFromCharStar)(char *);
 typedef void (*SetIntPtrFromCharStar)(void*, const char *);
 typedef char* (*GetCharStarFromIntPtr)(void *);
+typedef void (*MapPointerFn)(void *, void *, bool);
 typedef void* (*OverridenMethodFn)(void *, const char *);
 typedef void (*InvokeMethodFn)(void *, void *, void *);
 typedef void* (*CreateInstanceFn)(const char *);



More information about the Kde-bindings mailing list