[Kde-bindings] KDE/kdebindings/csharp/qyoto

Arno Rehn kde at arnorehn.de
Sat May 17 16:43:03 UTC 2008


SVN commit 808822 by arnorehn:

* Added delegate support. This is now possible:
	Connect(slider, SIGNAL("valueChanged(int)"), delegate(int i) {
		Console.WriteLine("value: {0}", i);
	});
  For the above to work you need either Mono 1.9+ or specify -langversion:linq.
  Alternatively, you can give the parameter types as generic arguments, like
  Connect<int>(...)

CCMAIL: kde-bindings at kde.org



 M  +7 -0      ChangeLog  
 M  +34 -0     core/QObjectExtras.cs  
 M  +55 -0     src/SmokeInvocation.cs  
 M  +5 -0      src/SmokeMarshallers.cs  
 A             src/delegateinvocation.h   [License: UNKNOWN]
 M  +1 -1      src/methodcall.cpp  
 M  +6 -5      src/qyoto.cpp  
 M  +2 -0      src/qyoto.h  
 M  +19 -0     src/qyotoshared.cpp  


--- trunk/KDE/kdebindings/csharp/qyoto/ChangeLog #808821:808822
@@ -3,6 +3,13 @@
 	* Don't build kimono because the classes won't compile.
 	* Fixed resolve_classname.
 	* Changed 'modules' to 'qyoto_modules' in QScintillaSharp, too.
+	* Added delegate support. This is now possible:
+		Connect(slider, SIGNAL("valueChanged(int)"), delegate(int i) {
+			Console.WriteLine("value: {0}", i);
+		});
+	  For the above to work you need either Mono 1.9+ or specify -langversion:linq.
+	  Alternatively, you can give the parameter types as generic arguments, like
+	  Connect<int>(...)
 
 2008-05-16  Richard Dale  <richard.j.dale at gmail.com>
 
--- trunk/KDE/kdebindings/csharp/qyoto/core/QObjectExtras.cs #808821:808822
@@ -4,6 +4,13 @@
 	using System.Runtime.InteropServices;
 	using System.Collections.Generic;
 
+	public delegate void NoArgDelegate();
+	public delegate void OneArgDelegate<T>(T arg);
+	public delegate void TwoArgDelegate<T1, T2>(T1 arg1, T2 arg2);
+	public delegate void ThreeArgDelegate<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
+	public delegate void FourArgDelegate<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+	public delegate void FiveArgDelegate<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
+
 	public partial class QObject : Qt, IDisposable {
 		private delegate void AddToListFn(IntPtr obj);
 		
@@ -14,6 +21,33 @@
 		private static extern void FindQObjectChildren(IntPtr parent, IntPtr regexp,
 									string childName, AddToListFn addFn);
 		
+		[DllImport("libqyotoshared", CharSet=CharSet.Ansi)]
+		private static extern bool ConnectDelegate(IntPtr obj, string signal, Delegate d);
+		
+		public static bool Connect(QObject obj, string signal, NoArgDelegate d) {
+			return ConnectDelegate((IntPtr) GCHandle.Alloc(obj), signal, d);
+		}
+		
+		public static bool Connect<T>(QObject obj, string signal, OneArgDelegate<T> d) {
+			return ConnectDelegate((IntPtr) GCHandle.Alloc(obj), signal, d);
+		}
+		
+		public static bool Connect<T1, T2>(QObject obj, string signal, TwoArgDelegate<T1, T2> d) {
+			return ConnectDelegate((IntPtr) GCHandle.Alloc(obj), signal, d);
+		}
+
+		public static bool Connect<T1, T2, T3>(QObject obj, string signal, ThreeArgDelegate<T1, T2, T3> d) {
+			return ConnectDelegate((IntPtr) GCHandle.Alloc(obj), signal, d);
+		}
+
+		public static bool Connect<T1, T2, T3, T4>(QObject obj, string signal, FourArgDelegate<T1, T2, T3, T4> d) {
+			return ConnectDelegate((IntPtr) GCHandle.Alloc(obj), signal, d);
+		}
+
+		public static bool Connect<T1, T2, T3, T4, T5>(QObject obj, string signal, FiveArgDelegate<T1, T2, T3, T4, T5> d) {
+			return ConnectDelegate((IntPtr) GCHandle.Alloc(obj), signal, d);
+		}
+
 		public T FindChild<T>(string name) {
 			IntPtr child = FindQObjectChild((IntPtr) GCHandle.Alloc(this), name);
 			if (child != IntPtr.Zero) {
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeInvocation.cs #808821:808822
@@ -369,6 +369,61 @@
 			}
 		}
 
+		static public void InvokeDelegate(Delegate d, IntPtr stack) {
+			unsafe {
+				MethodInfo mi = d.Method;
+				ParameterInfo[] parameters = mi.GetParameters();
+				object[] args = new object[parameters.Length];
+				StackItem* stackPtr = (StackItem*) stack;
+				for (int i = 0; i < args.Length; i++) {
+					if (parameters[i].ParameterType == typeof(bool)) {
+						args[i] = stackPtr[i].s_bool;
+					} else if (parameters[i].ParameterType == typeof(sbyte)) {
+						args[i] = stackPtr[i].s_char;
+					} else if (parameters[i].ParameterType == typeof(byte)) {
+						args[i] = stackPtr[i].s_uchar;
+					} else if (parameters[i].ParameterType == typeof(short)) {
+						args[i] = stackPtr[i].s_short;
+					} else if (parameters[i].ParameterType == typeof(ushort)) {
+						args[i] = stackPtr[i].s_ushort;
+					} else if (	parameters[i].ParameterType == typeof(int) 
+								|| parameters[i].ParameterType.IsEnum ) 
+					{
+						args[i] = stackPtr[i].s_int;
+					} else if (parameters[i].ParameterType == typeof(uint)) {
+						args[i] = stackPtr[i].s_uint;
+					} else if (parameters[i].ParameterType == typeof(long)) {
+						args[i] = stackPtr[i].s_long;
+					} else if (parameters[i].ParameterType == typeof(ulong)) {
+						args[i] = stackPtr[i].s_ulong;
+					} else if (parameters[i].ParameterType == typeof(float)) {
+						args[i] = stackPtr[i].s_float;
+					} else if (parameters[i].ParameterType == typeof(double)) {
+						args[i] = stackPtr[i].s_double;
+					} else if (parameters[i].ParameterType == typeof(string)) {
+						if (stackPtr[i].s_class != IntPtr.Zero) {
+							args[i] = (string) ((GCHandle) stackPtr[i].s_class).Target;
+#if DEBUG
+							DebugGCHandle.Free((GCHandle) stackPtr[i].s_class);
+#else
+							((GCHandle) stackPtr[i].s_class).Free();
+#endif
+						}
+					} else {
+						if (stackPtr[i].s_class != IntPtr.Zero) {
+							args[i] = ((GCHandle) stackPtr[i].s_class).Target;
+#if DEBUG
+							DebugGCHandle.Free((GCHandle) stackPtr[i].s_class);
+#else
+							((GCHandle) stackPtr[i].s_class).Free();
+#endif
+						}
+					}
+				}
+				d.DynamicInvoke(args);
+			}
+		}
+
 		static SmokeInvocation() {
 			Qyoto.Init_qyoto();
 			SmokeMarshallers.SetUp();
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeMarshallers.cs #808821:808822
@@ -112,6 +112,9 @@
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
 		public static extern void InstallInvokeCustomSlot(InvokeCustomSlotFn callback);
 		
+		[DllImport("libqyotoshared", CharSet=CharSet.Ansi)]
+		public static extern void InstallInvokeDelegate(InvokeDelegateFn callback);
+		
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
 		public static extern bool InstallGetProperty(OverridenMethodFn callback);
 		
@@ -206,6 +209,7 @@
 		public delegate IntPtr DictToMap(IntPtr ptr, int type);
 		public delegate IntPtr ConstructDict(string type1, string type2);
 		public delegate void SetPropertyFn(IntPtr obj, string name, IntPtr variant);
+		public delegate void InvokeDelegateFn(Delegate d, IntPtr stack);
 #endregion
 		
 #region marshalling functions
@@ -756,6 +760,7 @@
 
 			InstallCreateInstance(CreateInstance);
 			InstallInvokeCustomSlot(SmokeInvocation.InvokeCustomSlot);
+			InstallInvokeDelegate(SmokeInvocation.InvokeDelegate);
 			
 			InstallGetProperty(GetProperty);
 			InstallSetProperty(SetProperty);
--- trunk/KDE/kdebindings/csharp/qyoto/src/methodcall.cpp #808821:808822
@@ -27,7 +27,7 @@
 					&& (!_o->allocated || IsContainedInstance(_o) || application_terminated) ) 
 			{
 				_called = true;
-				_o->allocated = false;
+// 				_o->allocated = false;
 			}
 		} else {
 			// not a constructor, not static, pointer invalid -> object already destroyed
--- trunk/KDE/kdebindings/csharp/qyoto/src/qyoto.cpp #808821:808822
@@ -19,6 +19,7 @@
 #define _GNU_SOURCE
 #endif
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <QAbstractItemDelegate>
 #include <QAbstractItemView>
@@ -690,8 +691,9 @@
 Q_DECL_EXPORT void
 CallSmokeMethod(Smoke * smoke, int methodId, void * obj, Smoke::StackItem * sp, int items)
 {
+	Smoke::Method meth = smoke->methods[methodId];
 #ifdef DEBUG
-	printf("ENTER CallSmokeMethod(methodId: %d target: 0x%8.8x items: %d module: %s)\n", methodId, obj, items, smoke->moduleName());
+	printf("ENTER CallSmokeMethod(methodId: %d methodName: %s target: 0x%8.8x class: %s items: %d module: %s)\n", methodId, smoke->methodNames[meth.name], obj, smoke->className(meth.classId), items, smoke->moduleName());
 #endif
 
 	// C# operator methods must be static, and so some C++ instance methods with one argument
@@ -699,11 +701,10 @@
 	// examples of these and changes the args passed to the MethodCall() constructor. Note
 	// that 'operator>>' and 'operator<<' methods in C# must have a second arg of type int,
 	// and so they are mapped onto the instance methods Read() and Write() in C#.
-	Smoke::Method meth = smoke->methods[methodId];
 	if (	meth.numArgs == 1
-			&& qstrncmp("operator", qt_Smoke->methodNames[meth.name], sizeof("operator")) == 0
-			&& qstrncmp("operator<<", qt_Smoke->methodNames[meth.name], sizeof("operator<<")) != 0
-			&& qstrncmp("operator>>", qt_Smoke->methodNames[meth.name], sizeof("operator>>")) != 0 )
+			&& qstrncmp("operator", smoke->methodNames[meth.name], sizeof("operator")) == 0
+			&& qstrncmp("operator<<", smoke->methodNames[meth.name], sizeof("operator<<")) != 0
+			&& qstrncmp("operator>>", smoke->methodNames[meth.name], sizeof("operator>>")) != 0 )
 	{ // instance operator
 		obj = sp[1].s_class;
 		sp[1] = sp[2];
--- trunk/KDE/kdebindings/csharp/qyoto/src/qyoto.h #808821:808822
@@ -122,6 +122,8 @@
 extern Q_DECL_EXPORT OverridenMethodFn GetProperty;
 extern Q_DECL_EXPORT SetPropertyFn SetProperty;
 
+extern Q_DECL_EXPORT SetIntPtr InvokeDelegate;
+
 extern "C" {
 extern Q_DECL_EXPORT QMetaObject* parent_meta_object(void* obj);
 extern Q_DECL_EXPORT MocArgument* GetMocArgumentsNumber(QString replyType, QString member, int& number);
--- trunk/KDE/kdebindings/csharp/qyoto/src/qyotoshared.cpp #808821:808822
@@ -9,6 +9,7 @@
 #include "writeproperty.h"
 #include "readproperty.h"
 #include "invokeslot.h"
+#include "delegateinvocation.h"
 
 #ifdef DEBUG
 int do_debug = qtdb_gc;
@@ -43,6 +44,8 @@
 OverridenMethodFn GetProperty;
 SetPropertyFn SetProperty;
 
+SetIntPtr InvokeDelegate;
+
 void
 smokeStackToQtStack(Smoke::Stack stack, void ** o, int items, MocArgument* args)
 {
@@ -303,6 +306,22 @@
 extern "C"
 {
 
+Q_DECL_EXPORT void
+InstallInvokeDelegate(SetIntPtr callback)
+{
+	InvokeDelegate = callback;
+}
+
+Q_DECL_EXPORT bool
+ConnectDelegate(void* obj, const char* signal, void* delegate)
+{
+	smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(obj);
+	QObject *qobject = (QObject*) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QObject").index);
+	new DelegateInvocation(qobject, signal, delegate);
+	(*FreeGCHandle)(obj);
+	return true;
+}
+
 Q_DECL_EXPORT QMetaObject* parent_meta_object(void* obj) {
 	smokeqyoto_object* o = (smokeqyoto_object*) (*GetSmokeObject)(obj);
 	Smoke::ModuleIndex nameId = o->smoke->findMethodName(o->smoke->className(o->classId), "metaObject");



More information about the Kde-bindings mailing list