[Kde-bindings] playground/bindings/kimono

Richard Dale Richard_Dale at tipitina.demon.co.uk
Tue Feb 27 14:53:58 UTC 2007


SVN commit 637714 by rdale:

* Made the QMetaObject creation work correctly with nested subclasses

CCMAIL: kde-bindings at kde.org



 M  +4 -0      ChangeLog  
 M  +25 -29    Qyoto.cs  
 M  +0 -17     SmokeMarshallers.cs  
 M  +26 -43    qyoto.cpp  


--- trunk/playground/bindings/kimono/ChangeLog #637713:637714
@@ -1,3 +1,7 @@
+2007-02-27  Richard Dale  <rdale at foton.es>
+
+	* Made the QMetaObject creation work correctly with nested subclasses
+
 2007-02-24  Arno Rehn  <arno at arnorehn.de>
 
 	* Added ReadProperty and WriteProperty classes. Now custom properties can
--- trunk/playground/bindings/kimono/Qyoto.cs #637713:637714
@@ -54,9 +54,9 @@
 		public static extern void SetApplicationTerminated();
 
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
-		static extern IntPtr make_metaObject(IntPtr type, string className, bool isSmokeClass, 
-											IntPtr stringdata, int stringdataCount, 
-											 IntPtr data, int dataCount);
+		static extern IntPtr make_metaObject(	IntPtr obj, IntPtr parentMeta,
+												IntPtr stringdata, int stringdataCount, 
+											 	IntPtr data, int dataCount );
 		
 		public struct CPPMethod {
 			public string signature;
@@ -330,24 +330,20 @@
 			return props;
 		}
 		
-		public static QMetaObject MakeMetaObject(Type t) {
+		public static QMetaObject MakeMetaObject(Type t, QObject o) {
 			if (t == null) return null;
+#if DEBUG
+			Console.WriteLine("ENTER MakeMetaObject t => {0}", t);
+#endif
+			QMetaObject parentMeta = null;
+			if (	!IsSmokeClass(t.BaseType)
+					&& !metaObjects.TryGetValue(t.BaseType.Name, out parentMeta) ) 
+			{
+				// create QMetaObject
+				parentMeta = MakeMetaObject(t.BaseType, o);
+			}
 			
 			string className = t.Name;
-			GCHandle typeHandle = GCHandle.Alloc(t);
-			IntPtr metaObject;
-		
-			// 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;
 			
@@ -363,26 +359,27 @@
 			ICollection<CPPProperty> properties = GetProperties(t).Values;
 			
 			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) typeHandle, className, false, 
-												 (IntPtr)stringdata, metaData.StringData.Length,
-												 (IntPtr)data, metaData.Data.Length);
+					metaObject = make_metaObject(	(IntPtr)objHandle, 
+													parentMeta == null ? (IntPtr) 0 : (IntPtr) GCHandle.Alloc(parentMeta),
+												 	(IntPtr)stringdata, metaData.StringData.Length,
+												 	(IntPtr)data, metaData.Data.Length );
 				}
 			}
       
 			QMetaObject res = (QMetaObject)((GCHandle) metaObject).Target;
+			metaObjects.Add(t.Name, res);
 			return res;
 		}
-    
+		
 		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
@@ -390,8 +387,7 @@
 			QMetaObject res;
 			if (!metaObjects.TryGetValue(t.ToString(), out res)) {
 				// create QMetaObject
-				res = MakeMetaObject(t);
-				metaObjects.Add(t.ToString(), res);
+				res = MakeMetaObject(t, o);
 			}
 	
 #if DEBUG
@@ -399,7 +395,7 @@
 #endif
 
 			return res;
-		}
+		}	
 	}
 	
 	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
--- trunk/playground/bindings/kimono/SmokeMarshallers.cs #637713:637714
@@ -82,9 +82,6 @@
 		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 bool InstallGetProperty(OverridenMethodFn callback);
 		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
@@ -211,18 +208,6 @@
 			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);
-		}
-		
 		public static IntPtr GetProperty(IntPtr obj, string propertyName) {
 			object o = ((GCHandle) obj).Target;
 			Type t = o.GetType();
@@ -566,7 +551,6 @@
 		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);
 		
 		static private OverridenMethodFn getProperty = new OverridenMethodFn(GetProperty);
 		static private SetPropertyFn setProperty = new SetPropertyFn(SetProperty);
@@ -607,7 +591,6 @@
 			InstallCreateInstance(createInstance);
 			InstallInvokeCustomSlot(invokeCustomSlot);
 			InstallIsSmokeClass(isSmokeClass);
-			InstallGetParentMetaObject(getParentMetaObject);
 			
 			InstallGetProperty(getProperty);
 			InstallSetProperty(setProperty);
--- trunk/playground/bindings/kimono/qyoto.cpp #637713:637714
@@ -75,7 +75,6 @@
 static CreateInstanceFn CreateInstance;
 static InvokeCustomSlotFn InvokeCustomSlot;
 static IsSmokeClassFn IsSmokeClass;
-static GetIntPtr GetParentMetaObject;
 
 static OverridenMethodFn GetProperty;
 static SetPropertyFn SetProperty;
@@ -1336,12 +1335,6 @@
 }
 
 void
-InstallGetParentMetaObject(GetIntPtr callback)
-{
-	GetParentMetaObject = callback;
-}
-
-void
 InstallGetProperty(OverridenMethodFn callback)
 {
 	GetProperty = callback;
@@ -1502,47 +1495,37 @@
 	return true;
 }
 
-QMetaObject* parent_meta_object(void* type) {
-#ifdef DEBUG
-printf("ENTER make_metaObject()\n");
-#endif
-	void* obj = (*GetParentMetaObject)(type);
+QMetaObject* parent_meta_object(void* obj) {
 	smokeqyoto_object* o = value_obj_info(obj);
-	return (QMetaObject*) o->ptr;
+	Smoke::Index nameId = o->smoke->idMethodName("metaObject");
+	Smoke::Index meth = o->smoke->findMethod(o->classId, nameId);
+	if (meth <= 0) {
+		// Should never happen..
 	}
 
-void* make_metaObject(void* type, const char* className, bool isSmokeClass, 
-	const char* stringdata, int stringdata_count, const uint* data, int data_count)
+	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* obj, void* parentMeta, 
+						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 = 0;
+
+	if (parentMeta == 0) {
+		// The parent class is a Smoke class, so call metaObject() on the
+		// instance to get it via a smoke library call
+		parent = parent_meta_object(obj);
+	} else {
+		// The parent class is a custom C# class whose metaObject
+		// was constructed at runtime
+		smokeqyoto_object* o = value_obj_info(parentMeta);
+		parent = (QMetaObject *) o->ptr;
 	}
-	
-	QMetaObject* parent = parent_meta_object(type);
 
 	char* my_stringdata = new char[stringdata_count];
 	memcpy(my_stringdata, stringdata, stringdata_count * sizeof(char));



More information about the Kde-bindings mailing list