[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