[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-bindings
Subject:    [Kde-bindings] Qyoto: Some fixes
From:       "Paolo Capriotti" <p.capriotti () gmail ! com>
Date:       2006-05-29 16:13:16
Message-ID: 87b37d60605290913q373f22d3j45083d3f035669bc () mail ! gmail ! com
[Download RAW message or body]

Some fixes in qyoto/Qyoto.cs:
* To avoid virtual method dispatch resulting in infinite loop, the
meta object instance is now created in c++ code using smoke (just as
in qtruby).
* Qyoto.GetMetaObject now works for Qt types as well
* Decommented code in set_obj_info. This function is used by the
return value marshaller for non-primitive types and by
make_metaObject.

Paolo Capriotti

["fix.diff" (text/x-patch)]

Index: qyoto.cpp
===================================================================
--- qyoto.cpp	(revision 546244)
+++ qyoto.cpp	(working copy)
@@ -49,7 +49,7 @@
 #include "smoke.h"
 
 #define QYOTO_VERSION "0.0.1"
-// #define DEBUG
+#define DEBUG
 
 extern Smoke *qt_Smoke;
 extern void init_qt_Smoke();
@@ -164,10 +164,9 @@
 void *
 set_obj_info(const char * className, smokeqyoto_object * o)
 {
-//	void * obj = (*CreateInstance)(className);
-//	(*SetSmokeObject)(obj, o);
-//	return obj;
-	return 0;
+	void * obj = (*CreateInstance)(className);
+	(*SetSmokeObject)(obj, o);
+	return obj;
 }
 
 Marshall::HandlerFn getMarshallFn(const SmokeType &type);
@@ -942,11 +941,8 @@
 			strcmp(m.signature(), signatureStr) == 0)
 			break;
 	}
-
-#ifdef DEBUG  
+	
 	printf("emitting signal %d\n", i);
-#endif
-
 	EmitSignal signal(qobj, i, items, args, sp);
 	signal.next();
 
@@ -958,32 +954,45 @@
 }
 
 
-void * 
-make_metaObject(QMetaObject* parent, const char* stringdata, const uint* data) {
-#ifdef DEBUG
-	printf("parent = %x\n", parent);
+void* make_metaObject(void* obj, const char* stringdata, const uint* data) {
 	printf("stringdata = %s\n", stringdata);
 	printf("data = %x\n", data);
-#endif
-  // create a QMetaObject on the stack
-  QMetaObject tmp = {{
-    parent,
-    stringdata,
-    data,
-    0
-  }};
-  
-  // copy it to the heap
-  QMetaObject* meta = new QMetaObject;
-  *meta = tmp;
-  
-  // create smoke object
-  smokeqyoto_object* m = (smokeqyoto_object*)malloc(sizeof(smokeqyoto_object));
-  m->smoke = qt_Smoke;
-  m->classId = qt_Smoke->idClass("QMetaObject");
-  m->ptr = meta;
-  
-  return m;
+	
+	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;
+	}
+	
+	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);
+	
+	QMetaObject* parent = (QMetaObject*) i[0].s_voidp;
+	
+	// create a QMetaObject on the stack
+	QMetaObject tmp = {{
+		parent,
+		stringdata,
+		data,
+		0
+	}};
+	
+	// copy it to the heap
+	QMetaObject* meta = new QMetaObject;
+	*meta = tmp;
+	
+	// create smoke object
+	smokeqyoto_object* m = (smokeqyoto_object*)malloc(sizeof(smokeqyoto_object));
+	m->smoke = qt_Smoke;
+	m->classId = qt_Smoke->idClass("QMetaObject");
+	m->ptr = meta;
+	
+	// create wrapper C# instance
+	return set_obj_info("Qt.QMetaObject", m);
 }
 
 void
Index: qyoto/QObject.cs
===================================================================
--- qyoto/QObject.cs	(revision 546244)
+++ qyoto/QObject.cs	(working copy)
@@ -54,6 +54,7 @@
 		public virtual QMetaObject MetaObject() {
 			return ProxyQObject().MetaObject();
 		}
+    
 		// int qt_metacall(QMetaObject::Call arg1,int arg2,void** arg3); >>>> NOT \
CONVERTED  public QObject(QObject parent) : this((Type) null) {
 			CreateProxy();
Index: qyoto/Qyoto.cs
===================================================================
--- qyoto/Qyoto.cs	(revision 546244)
+++ qyoto/Qyoto.cs	(working copy)
@@ -21,7 +21,7 @@
 		/// This hashtable has classe names as keys, and QMetaObjects as values
 		static Hashtable metaObjects = new Hashtable();
 		
-		public static void GetSlotSignatures(Type t) {
+		public static Hashtable GetSlotSignatures(Type t) {
 			
 			/// Remove the old object if it already exists
 			classes.Remove(t.Name);
@@ -40,6 +40,7 @@
 			}
 			
 			classes.Add(t.Name, slots);
+			return slots;
 		}
 		
 		public static string[] GetSignalSignatures(Type t) {
@@ -174,61 +175,62 @@
 			}
 		}
     
-		public static QMetaObject MakeMetaObject(Type t) {
-#if DEBUG
-			Console.WriteLine("ENTER: MakeMetaObject.  t => {0}", t);
-#endif
+		public static QMetaObject MakeMetaObject(Type t, QObject o) {
+			if (t == null) return null;
 		
-			if (t == null || typeof(QObject).IsAssignableFrom(t)) return null;
-		
 			string className = t.ToString();
 			Hashtable slotTable = (Hashtable)classes[className];
+			
 		
 			ICollection slots;
 			if (slotTable != null)
 				slots = slotTable.Values;
 			else {
 				// build slot table
-				GetSlotSignatures(t);
-				slotTable = (Hashtable)classes[className];
-				slots = slotTable.Values;
+				slots = GetSlotSignatures(t).Values;
 			}
-		
+
 			string[] signals = GetSignalSignatures(t);
 			QyotoMetaData metaData = new QyotoMetaData(className, signals, slots);
-			GCHandle parentMetaObject = GCHandle.Alloc(GetMetaObject(t.BaseType));
-			IntPtr metaSmokeObject;
-		
+			
+			GCHandle objHandle = GCHandle.Alloc(o);
+			IntPtr metaObject;
+			
 			unsafe {
 				fixed (byte* stringdata = metaData.StringData)
 				fixed (int* data = metaData.Data) {
-					metaSmokeObject = make_metaObject((IntPtr)parentMetaObject, (IntPtr)stringdata, \
(IntPtr)data); +					metaObject = make_metaObject((IntPtr)objHandle, \
(IntPtr)stringdata, (IntPtr)data);  }
 			}
       
-			// create a new C# QMetaObject and replace its
-			// inner _smokeObject with that returned from make_metaObject
-			QMetaObject res = new QMetaObject();
-			FieldInfo fieldInfo = typeof(QMetaObject).GetField(  "_smokeObject", 
-																BindingFlags.NonPublic 
-																| BindingFlags.GetField
-																| BindingFlags.Instance );
-			((GCHandle)fieldInfo.GetValue(res)).Free();
-			fieldInfo.SetValue(res, metaSmokeObject);
-		
-#if DEBUG
-			Console.WriteLine("LEAVE MakeMetaObject");
-#endif
+			QMetaObject res = (QMetaObject)((GCHandle) metaObject).Target;
 			return res;
 		}
     
-		public static QMetaObject GetMetaObject(Type t) {
-			QMetaObject res = (QMetaObject)metaObjects[t.ToString()];
-			if (res == null) {
-				res = MakeMetaObject(t);
-				metaObjects[t.ToString()] = res;
+		public static QMetaObject GetMetaObject(Type t, QObject o) {
+			object[] attr = t.GetCustomAttributes(typeof(SmokeClass), false);
+			if (attr.Length > 0) {
+				// qt class: simply call the MetaObject method
+				MethodInfo metaObjectMethod = t.GetMethod("MetaObject", BindingFlags.Public | \
BindingFlags.Instance); +				if (metaObjectMethod == null) {
+					// this should never happen
+					Console.WriteLine("** Cannot find MetaObject method **");
+					return null;
+				}
+				else {
+					return (QMetaObject)metaObjectMethod.Invoke(o, new object[] {});
+				}
 			}
-			return res;
+			else {
+				// user defined class: retrieve QMetaObject from the hashtable
+				QMetaObject res = (QMetaObject)metaObjects[t.ToString()];
+				if (res == null) {
+					// create QMetaObject
+					res = MakeMetaObject(t, o);
+					metaObjects[t.ToString()] = res;
+				}
+				return res;
+			}
 		}
 	}
 	
Index: SmokeInvocation.cs
===================================================================
--- SmokeInvocation.cs	(revision 546244)
+++ SmokeInvocation.cs	(working copy)
@@ -200,7 +200,7 @@
 			Type klass = Type.GetType(className);
 
 			Type[] constructorParamTypes = new Type[1];
-			constructorParamTypes[0] = Type.GetType("System.Type");
+			constructorParamTypes[0] = typeof(Type);
 			ConstructorInfo constructorInfo = klass.GetConstructor(BindingFlags.NonPublic 
 					| BindingFlags.Instance, null, new Type[ ] { typeof( Type ) } , null);
 			if (constructorInfo == null) {



_______________________________________________
Kde-bindings mailing list
Kde-bindings@kde.org
https://mail.kde.org/mailman/listinfo/kde-bindings


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic