[Kde-bindings] playground/bindings/kimono

Arno Rehn kde at arnorehn.de
Wed Feb 21 17:53:47 UTC 2007


SVN commit 636018 by arnorehn:

* QMetaObjects are now correctly inherited.
* If there was a request for a QMetaObject of a native Qt class, a new
  QMetaObject was created with all the signals and slots of the class and
  the native QMetaObject was just used as a parent. The resulting object had
  every definition twice. Fixed.

CCMAIL: kde-bindings at kde.org



 M  +8 -0      ChangeLog  
 M  +24 -9     Qyoto.cs  
 M  +17 -0     SmokeMarshallers.cs  
 M  +42 -15    qyoto.cpp  


--- trunk/playground/bindings/kimono/ChangeLog #636017:636018
@@ -1,3 +1,11 @@
+2007-02-21  Arno Rehn  <arno at arnorehn.de>
+
+	* QMetaObjects are now correctly inherited.
+	* If there was a request for a QMetaObject of a native Qt class, a new
+	  QMetaObject was created with all the signals and slots of the class and
+	  the native QMetaObject was just used as a parent. The resulting object had
+	  every definition twice. Fixed.
+
 2007-02-20  Richard Dale  <rdale at foton.es>
 
 	* Commented out QList<QHostAddress> marshallers as it caused a linking
--- trunk/playground/bindings/kimono/Qyoto.cs #636017:636018
@@ -54,7 +54,8 @@
 		public static extern void SetApplicationTerminated();
 
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
-		static extern IntPtr make_metaObject(IntPtr parent, IntPtr stringdata, int stringdataCount, 
+		static extern IntPtr make_metaObject(IntPtr type, string className, bool isSmokeClass, 
+											IntPtr stringdata, int stringdataCount, 
 											 IntPtr data, int dataCount);
 		
 		public struct CPPMethod {
@@ -230,7 +231,6 @@
 					string sig = attr.Signature;
 					if (sig == "")
 						sig = SignatureFromMethodInfo(mi);
-					Console.WriteLine(sig);
 					GetCPPMethodInfo(sig, out cppinfo.signature, out cppinfo.type);
 					
 					cppinfo.mi = mi;
@@ -330,10 +330,24 @@
 			return props;
 		}
 		
-		public static QMetaObject MakeMetaObject(Type t, QObject o) {
+		public static QMetaObject MakeMetaObject(Type t) {
 			if (t == null) return null;
+			
+			string className = t.Name;
+			GCHandle typeHandle = GCHandle.Alloc(t);
+			IntPtr metaObject;
 		
-			string className = t.ToString();
+			// if it is a Smoke class, don't build a new metaobject
+			// this would have the 'real' metaobject just as a parent and
+			// would be cluttered with duplicate signal/slot definitions
+			if (IsSmokeClass(t)) {
+				metaObject = make_metaObject((IntPtr) typeHandle, className, true, 
+							(IntPtr)0, 0,
+							(IntPtr)0, 0);
+				QMetaObject original = (QMetaObject)((GCHandle) metaObject).Target;
+				return original;
+			}
+		
 			Dictionary<string, CPPMethod> slotTable;
 			ICollection<CPPMethod> slots;
 			
@@ -350,13 +364,10 @@
 			
 			QyotoMetaData metaData = new QyotoMetaData(className, signals, slots, GetClassInfos(t), properties);
 			
-			GCHandle objHandle = GCHandle.Alloc(o);
-			IntPtr metaObject;
-			
 			unsafe {
 				fixed (byte* stringdata = metaData.StringData)
 				fixed (uint* data = metaData.Data) {
-					metaObject = make_metaObject((IntPtr)objHandle, 
+					metaObject = make_metaObject((IntPtr) typeHandle, className, false, 
 												 (IntPtr)stringdata, metaData.StringData.Length,
 												 (IntPtr)data, metaData.Data.Length);
 				}
@@ -368,6 +379,10 @@
     
 		public static QMetaObject GetMetaObject(QObject o) {
 			Type t = o.GetType();
+			return GetMetaObject(t);
+		}
+		
+		public static QMetaObject GetMetaObject(Type t) {
 #if DEBUG
 			Console.WriteLine("ENTER GetMetaObject t => {0}", t);
 #endif
@@ -375,7 +390,7 @@
 			QMetaObject res;
 			if (!metaObjects.TryGetValue(t.ToString(), out res)) {
 				// create QMetaObject
-				res = MakeMetaObject(t, o);
+				res = MakeMetaObject(t);
 				metaObjects.Add(t.ToString(), res);
 			}
 	
--- trunk/playground/bindings/kimono/SmokeMarshallers.cs #636017:636018
@@ -82,6 +82,9 @@
 		public static extern bool InstallIsSmokeClass(IsSmokeClassFn callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
+		public static extern bool InstallGetParentMetaObject(GetIntPtr callback);
+		
+		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
 		public static extern void InstallIntPtrToCharStarStar(GetIntPtr callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
@@ -200,6 +203,18 @@
 			SetSmokeObject(instance, smokeObjectPtr);
 			return;
 		}
+		
+		public static IntPtr GetParentMetaObject(IntPtr type) {
+			Type t = (Type) ((GCHandle) type).Target;
+// 			Type t = Type.GetType(name);
+			Type baseType = t.BaseType;
+			QMetaObject mo = Qyoto.GetMetaObject(baseType);
+			if (mo == null) {
+				Console.WriteLine("Qyoto.GetMetaObject() returned NULL");
+				return (IntPtr) 0;
+			}
+			return (IntPtr) GCHandle.Alloc(mo);
+		}
 
 		// The key is an IntPtr corresponding to the address of the C++ instance,
 		// and the value is a the C# instance. This is used to prevent garbage
@@ -507,6 +522,7 @@
 		static private CreateInstanceFn createInstance = new CreateInstanceFn(CreateInstance);
 		static private InvokeCustomSlotFn invokeCustomSlot = new InvokeCustomSlotFn(SmokeInvocation.InvokeCustomSlot);
 		static private IsSmokeClassFn isSmokeClass = new IsSmokeClassFn(Qyoto.IsSmokeClass);
+		static private GetIntPtr getParentMetaObject = new GetIntPtr(GetParentMetaObject);
 		
 		public static void SetUp() {
 			InstallFreeGCHandle(freeGCHandle);
@@ -544,6 +560,7 @@
 			InstallCreateInstance(createInstance);
 			InstallInvokeCustomSlot(invokeCustomSlot);
 			InstallIsSmokeClass(isSmokeClass);
+			InstallGetParentMetaObject(getParentMetaObject);
 		}
 #endregion
 
--- trunk/playground/bindings/kimono/qyoto.cpp #636017:636018
@@ -75,6 +75,7 @@
 static CreateInstanceFn CreateInstance;
 static InvokeCustomSlotFn InvokeCustomSlot;
 static IsSmokeClassFn IsSmokeClass;
+static GetIntPtr GetParentMetaObject;
 
 // Maps from a classname in the form Qt::Widget to an int id
 QHash<int,char *> classname;
@@ -1232,6 +1233,12 @@
 }
 
 void
+InstallGetParentMetaObject(GetIntPtr callback)
+{
+	GetParentMetaObject = callback;
+}
+
+void
 SetApplicationTerminated()
 {
 	application_terminated = true;
@@ -1380,28 +1387,48 @@
 	return true;
 }
 
-QMetaObject* parent_meta_object(void* obj) {
+QMetaObject* parent_meta_object(void* type) {
 #ifdef DEBUG
 printf("ENTER make_metaObject()\n");
 #endif
+	void* obj = (*GetParentMetaObject)(type);
 	smokeqyoto_object* o = value_obj_info(obj);
-	Smoke::Index nameId = o->smoke->idMethodName("metaObject");
-	Smoke::Index meth = o->smoke->findMethod(o->classId, nameId);
-	if (meth <= 0) {
-		// Should never happen..
-		return 0;
+	return (QMetaObject*) o->ptr;
 	}
 
-	Smoke::Method &methodId = o->smoke->methods[o->smoke->methodMaps[meth].method];
-	Smoke::ClassFn fn = o->smoke->classes[methodId.classId].classFn;
-	Smoke::StackItem i[1];
-	(*fn)(methodId.method, o->ptr, i);
-	return (QMetaObject*) i[0].s_voidp;
-}
+void* make_metaObject(void* type, const char* className, bool isSmokeClass, 
+	const char* stringdata, int stringdata_count, const uint* data, int data_count)
+{
+	// if it is a Smoke class, don't build a new metaobject
+	// this would have the 'real' metaobject just as a parent and
+	// would be cluttered with duplicate signal/slot definitions
+	// instead use the original one
+	if (isSmokeClass) {
+		Smoke::Index classId = qt_Smoke->idClass(className);
+		Smoke::Index nameId = qt_Smoke->idMethodName("staticMetaObject");
+		Smoke::Index meth = qt_Smoke->findMethod(classId, nameId);
+		if (meth <= 0) {
+			// Should never happen..
+			return 0;
+		}
+	
+		Smoke::Method &methodId = qt_Smoke->methods[qt_Smoke->methodMaps[meth].method];
+		Smoke::ClassFn fn = qt_Smoke->classes[methodId.classId].classFn;
+		Smoke::StackItem i[1];
+		(*fn)(methodId.method, 0, i);
+		QMetaObject* meta = (QMetaObject*) i[0].s_voidp;
+		
+		// create smoke object
+		smokeqyoto_object  * m = alloc_smokeqyoto_object(	true, 
+									qt_Smoke, 
+									qt_Smoke->idClass("QMetaObject"), 
+									meta );		
+		// create wrapper C# instance
+		return set_obj_info("Qyoto.QMetaObject", m);
+	}
+	
+	QMetaObject* parent = parent_meta_object(type);
 
-void* make_metaObject(void* obj, const char* stringdata, int stringdata_count, const uint* data, int data_count) {
-	QMetaObject* parent = parent_meta_object(obj);
-
 	char* my_stringdata = new char[stringdata_count];
 	memcpy(my_stringdata, stringdata, stringdata_count * sizeof(char));
 	



More information about the Kde-bindings mailing list