[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